Skip to content

Commit

Permalink
feat(engine): add plaintext and gc engine, wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamie-Cui committed Nov 22, 2024
1 parent f9e2256 commit 10707d1
Show file tree
Hide file tree
Showing 16 changed files with 297 additions and 150 deletions.
3 changes: 3 additions & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
examples
cmake
docs
build
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ Yacl-r is a fork and extension of the C++ crypto library [secretflow/yacl](https

- **bazel**: [.bazelversion](.bazelversion) file describes the recommended version of bazel. We recommend to use the official [bazelisk](https://github.com/bazelbuild/bazelisk?tab=readme-ov-file#installation) to manage bazel version.
- **gcc >= 10.3**
- **[cmake](https://cmake.org/getting-started/)**
- **[ninja/ninja-build](https://ninja-build.org/)**
- **Perl 5 with core modules** (Required by [OpenSSL](https://github.com/openssl/openssl/blob/master/INSTALL.md#prerequisites))

Expand Down
40 changes: 40 additions & 0 deletions examples/hesm2/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2024 Guowei Ling.
#
# 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.

load("@yacl//bazel:yacl.bzl", "yacl_cc_binary")

package(default_visibility = ["//visibility:public"])

yacl_cc_binary(
name = "sm2_example",
srcs = [
"ahesm2.cc",
"ahesm2.h",
"ciphertext.h",
"config.cc",
"config.h",
"main.cc",
"private_key.h",
"public_key.h",
"t1.h",
"t2.h",
],
deps = [
"@yacl//yacl/crypto/ecc:spi",
"@yacl//yacl/crypto/ecc/openssl",
"@yacl//yacl/crypto/tools:cuckoo_index", # 添加 cuckoo_index 依赖
"@yacl//yacl/math/mpint",
"@yacl//yacl/utils/spi",
],
)
21 changes: 21 additions & 0 deletions yacl/crypto/tools/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,24 @@ yacl_cc_binary(
"@com_github_google_benchmark//:benchmark_main",
],
)

yacl_cc_library(
name = "cuckoo_index",
srcs = ["cuckoo_index.cc"],
hdrs = ["cuckoo_index.h"],
linkopts = ["-lm"],
deps = [
"//yacl/base:exception",
"//yacl/base:int128",
"@com_google_absl//absl/types:span",
],
)

yacl_cc_test(
name = "cuckoo_index_test",
srcs = ["cuckoo_index_test.cc"],
deps = [
":cuckoo_index",
"//yacl/crypto/rand",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "yacl/utils/cuckoo_index.h"
#include "yacl/crypto/tools/cuckoo_index.h"

#include <cmath>
#include <set>
Expand Down Expand Up @@ -147,4 +147,4 @@ uint8_t CuckooIndex::MinCollidingHashIdx(uint64_t bin_index) const {
return -1;
}

} // namespace yacl
} // namespace yacl
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "yacl/utils/cuckoo_index.h"
#include "yacl/crypto/tools/cuckoo_index.h"

#include <random>

Expand Down
39 changes: 39 additions & 0 deletions yacl/engine/plaintext/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2022 Ant Group Co., Ltd.
#
# 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.

load("//bazel:yacl.bzl", "yacl_cc_library", "yacl_cc_test")

package(default_visibility = ["//visibility:public"])

yacl_cc_library(
name = "executor",
srcs = ["executor.cc"],
hdrs = ["executor.h"],
deps = [
"//yacl/base:dynamic_bitset",
"//yacl/base:int128",
"//yacl/io/circuit:bristol_fashion",
],
)

yacl_cc_test(
name = "executor_test",
srcs = ["executor_test.cc"],
data = ["//yacl/io/circuit:circuit_data"],
deps = [
"executor",
"//yacl/crypto/block_cipher:symmetric_crypto",
"//yacl/crypto/rand",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "yacl/utils/circuit_executor.h"
#include "yacl/engine/plaintext/executor.h"

namespace yacl {
namespace yacl::engine {

namespace {
class PlaintextCore {
Expand All @@ -25,24 +25,13 @@ class PlaintextCore {
};
} // namespace

template <typename T>
void PlainExecutor<T>::LoadCircuitFile(const std::string& path) {
void PlainExecutor::LoadCircuitFile(const std::string& path) {
io::CircuitReader reader(path);
reader.ReadAll();
circ_ = reader.StealCirc();
}

template <typename T>
void PlainExecutor<T>::SetupInputs(absl::Span<T> inputs) {
YACL_ENFORCE(inputs.size() == circ_->niv);
for (auto input : inputs) {
wires_.append(input);
}
wires_.resize(circ_->nw);
}

template <typename T>
void PlainExecutor<T>::Exec() {
void PlainExecutor::Exec() {
// Evaluate all gates, sequentially
for (const auto& gate : circ_->gates) {
switch (gate.op) {
Expand Down Expand Up @@ -82,22 +71,5 @@ void PlainExecutor<T>::Exec() {
}
}

template <typename T>
void PlainExecutor<T>::Finalize(absl::Span<T> outputs) {
YACL_ENFORCE(outputs.size() >= circ_->nov);

size_t index = wires_.size();
for (size_t i = 0; i < circ_->nov; ++i) {
dynamic_bitset<T> result(circ_->now[i]);
for (size_t j = 0; j < circ_->now[i]; ++j) {
result[j] = wires_[index - circ_->now[i] + j];
}
outputs[circ_->nov - i - 1] = *(T*)result.data();
index -= circ_->now[i];
}
}

template class PlainExecutor<uint64_t>;
template class PlainExecutor<uint128_t>;

} // namespace yacl
} // namespace yacl::engine
99 changes: 99 additions & 0 deletions yacl/engine/plaintext/executor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2024 Ant Group Co., Ltd.
//
// 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 <memory>

#include "yacl/base/byte_container_view.h"
#include "yacl/base/dynamic_bitset.h"
#include "yacl/base/int128.h"
#include "yacl/io/circuit/bristol_fashion.h"

namespace yacl::engine {

// plaintext protocol that executes everything without link

class PlainExecutor {
public:
// Constructor
explicit PlainExecutor() = default;

// Load circuit from file (local operation)
void LoadCircuitFile(const std::string &path);

// Setup the input wire (local operation)
template <typename T = uint64_t>
void SetupInputs(absl::Span<T> inputs) {
YACL_ENFORCE(inputs.size() == circ_->niv);

dynamic_bitset<uint128_t> input_wires;
input_wires.resize(sizeof(T) * 8 * inputs.size());
std::memcpy(input_wires.data(), inputs.data(), inputs.size() * sizeof(T));
wires_.append(input_wires);
wires_.resize(circ_->nw);
}

// Setup the input wire
void SetupInputBytes(ByteContainerView bytes) {
wires_.resize(circ_->nw);
std::memcpy(wires_.data(), bytes.data(), bytes.size());
}

// Execute the circuit
void Exec();

// Finalize and get the result
template <typename T = uint64_t>
void Finalize(absl::Span<T> outputs) {
YACL_ENFORCE(outputs.size() >= circ_->nov);
size_t index = wires_.size();
for (size_t i = 0; i < circ_->nov; ++i) {
dynamic_bitset<T> result(circ_->now[i]);
for (size_t j = 0; j < circ_->now[i]; ++j) {
result[j] = wires_[index - circ_->now[i] + j];
}
outputs[circ_->nov - i - 1] = *(T *)result.data();
index -= circ_->now[i];
}
}

std::vector<uint8_t> FinalizeBytes() {
// Count the totoal number of output wires (a.k.a. output bits)
size_t total_out_bitnum = 0;
for (size_t i = 0; i < circ_->nov; ++i) {
total_out_bitnum += circ_->now[i];
}

// Make sure that the circuit output wire is full bytes
YACL_ENFORCE(total_out_bitnum % 8 == 0);

const size_t wire_size = wires_.size();
dynamic_bitset<uint128_t> result(total_out_bitnum);
for (size_t i = 0; i < total_out_bitnum; ++i) {
result[total_out_bitnum - i - 1] = wires_[wire_size - i - 1];
}
YACL_ENFORCE(result.size() == total_out_bitnum);
std::vector<uint8_t> out(total_out_bitnum / 8);
std::memcpy(out.data(), result.data(), out.size());
return out;
}

private:
// NOTE: please make sure you use the correct order of wires
dynamic_bitset<uint128_t> wires_; // shares
std::shared_ptr<io::BFCircuit> circ_; // bristol fashion circuit
};

} // namespace yacl::engine
Loading

0 comments on commit 10707d1

Please sign in to comment.