From dca1d6cb3454491b8131b5151731f5d1351e5140 Mon Sep 17 00:00:00 2001 From: Ryan Burn Date: Fri, 9 Aug 2024 11:07:37 -0700 Subject: [PATCH] feat: compute product lengths for variable length multiexponentiations (PROOF-896) (#164) * compute product lengths * fix comment --- sxt/multiexp/pippenger2/BUILD | 10 +++ .../pippenger2/variable_length_computation.cc | 62 +++++++++++++++++++ .../pippenger2/variable_length_computation.h | 29 +++++++++ .../variable_length_computation.t.cc | 58 +++++++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 sxt/multiexp/pippenger2/variable_length_computation.cc create mode 100644 sxt/multiexp/pippenger2/variable_length_computation.h create mode 100644 sxt/multiexp/pippenger2/variable_length_computation.t.cc diff --git a/sxt/multiexp/pippenger2/BUILD b/sxt/multiexp/pippenger2/BUILD index 09e66a9f..a8279ec5 100644 --- a/sxt/multiexp/pippenger2/BUILD +++ b/sxt/multiexp/pippenger2/BUILD @@ -241,3 +241,13 @@ sxt_cc_component( "//sxt/memory/resource:pinned_resource", ], ) + +sxt_cc_component( + name = "variable_length_computation", + test_deps = [ + "//sxt/base/test:unit_test", + ], + deps = [ + "//sxt/base/container:span", + ], +) diff --git a/sxt/multiexp/pippenger2/variable_length_computation.cc b/sxt/multiexp/pippenger2/variable_length_computation.cc new file mode 100644 index 00000000..3ca6a2ab --- /dev/null +++ b/sxt/multiexp/pippenger2/variable_length_computation.cc @@ -0,0 +1,62 @@ +/** Proofs GPU - Space and Time's cryptographic proof algorithms on the CPU and GPU. + * + * Copyright 2024-present Space and Time Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sxt/multiexp/pippenger2/variable_length_computation.h" + +#include + +#include "sxt/base/error/assert.h" + +namespace sxt::mtxpp2 { +//-------------------------------------------------------------------------------------------------- +// compute_product_length_table +//-------------------------------------------------------------------------------------------------- +void compute_product_length_table(basct::span& product_lengths, + basct::cspan bit_widths, + basct::cspan output_lengths, unsigned first, + unsigned length) noexcept { + auto num_products = product_lengths.size(); + auto num_outputs = bit_widths.size(); + SXT_DEBUG_ASSERT( + // clang-format off + num_products >= num_outputs && + product_lengths.size() == num_products && + bit_widths.size() == num_outputs && + output_lengths.size() == num_outputs + // clang-format on + ); + + // find the index of the first output longer than + auto output_first = [&] noexcept { + auto iter = std::find_if(output_lengths.begin(), output_lengths.end(), + [&](double output_length) noexcept { return output_length > first; }); + return static_cast(std::distance(output_lengths.begin(), iter)); + }(); + + // fill in product lengths + unsigned product_index = 0; + for (auto output_index = output_first; output_index < num_outputs; ++output_index) { + auto output_length = output_lengths[output_index]; + SXT_DEBUG_ASSERT(output_length > first); + auto product_length = std::min(output_length - first, length); + auto bit_width = bit_widths[output_index]; + for (unsigned bit_index = 0; bit_index < bit_width; ++bit_index) { + product_lengths[product_index++] = product_length; + } + } + product_lengths = product_lengths.subspan(0, product_index); +} +} // namespace sxt::mtxpp2 diff --git a/sxt/multiexp/pippenger2/variable_length_computation.h b/sxt/multiexp/pippenger2/variable_length_computation.h new file mode 100644 index 00000000..1d9ff9ea --- /dev/null +++ b/sxt/multiexp/pippenger2/variable_length_computation.h @@ -0,0 +1,29 @@ +/** Proofs GPU - Space and Time's cryptographic proof algorithms on the CPU and GPU. + * + * Copyright 2024-present Space and Time Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "sxt/base/container/span.h" + +namespace sxt::mtxpp2 { +//-------------------------------------------------------------------------------------------------- +// compute_product_length_table +//-------------------------------------------------------------------------------------------------- +void compute_product_length_table(basct::span& product_lengths, + basct::cspan bit_widths, + basct::cspan output_lengths, unsigned first, + unsigned length) noexcept; +} // namespace sxt::mtxpp2 diff --git a/sxt/multiexp/pippenger2/variable_length_computation.t.cc b/sxt/multiexp/pippenger2/variable_length_computation.t.cc new file mode 100644 index 00000000..70a77045 --- /dev/null +++ b/sxt/multiexp/pippenger2/variable_length_computation.t.cc @@ -0,0 +1,58 @@ +/** Proofs GPU - Space and Time's cryptographic proof algorithms on the CPU and GPU. + * + * Copyright 2024-present Space and Time Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "sxt/multiexp/pippenger2/variable_length_computation.h" + +#include + +#include "sxt/base/test/unit_test.h" + +using namespace sxt; +using namespace sxt::mtxpp2; + +TEST_CASE("we can fill in the table of product lengths") { + std::vector product_lengths_data(10); + std::vector bit_widths; + std::vector output_lengths; + + basct::span product_lengths = {product_lengths_data.data(), 1}; + + SECTION("we can compute the product length of a single output of a single bit") { + bit_widths = {1}; + output_lengths = {10}; + compute_product_length_table(product_lengths, bit_widths, output_lengths, 0, 5); + REQUIRE(product_lengths.size() == 1); + REQUIRE(product_lengths[0] == 5); + } + + SECTION("we handle the case when output_length is less than length") { + bit_widths = {1}; + output_lengths = {10}; + compute_product_length_table(product_lengths, bit_widths, output_lengths, 0, 20); + REQUIRE(product_lengths.size() == 1); + REQUIRE(product_lengths[0] == 10); + } + + SECTION("we handle output of more than a single bit") { + bit_widths = {2}; + product_lengths = {product_lengths_data.data(), 2}; + output_lengths = {10}; + compute_product_length_table(product_lengths, bit_widths, output_lengths, 0, 5); + REQUIRE(product_lengths.size() == 2); + REQUIRE(product_lengths[0] == 5); + REQUIRE(product_lengths[1] == 5); + } +}