Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add leichi algorithm to HEU #80

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions heu/library/algorithms/leichi_paillier/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
load("@yacl//bazel:yacl.bzl", "yacl_cc_library", "yacl_cc_test")

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

test_suite(
name = "leichi_paillier_tests",
)

config_setting(
name = "use_leichi",
values = {"define": "enable_leichi=true"},
)

yacl_cc_library(
name = "leichi_paillier_defs",
hdrs = ["leichi.h"],
deps = [":leichi_paillier"],
)

yacl_cc_library(
name = "leichi_paillier",
srcs = select({
":use_leichi":[
"vector_decryptor.cc",
"vector_encryptor.cc",
"vector_evaluator.cc",
"key_generator.cc",
"public_key.cc",
"secret_key.cc",
"plaintext.cc",
"ciphertext.cc",
"utils.cc",
"runtime.cc",
],
"//conditions:default":[],
}),

hdrs = select({
":use_leichi":[
"plaintext.h",
"ciphertext.h",
"vector_decryptor.h",
"vector_encryptor.h",
"vector_evaluator.h",
"key_generator.h",
"public_key.h",
"secret_key.h",
"leichi.h",
"utils.h",
"runtime.h",
],
"//conditions:default":[],
}),

visibility = ["//visibility:public"],

deps = select({
":use_leichi":[
"//heu/library/algorithms/util",
"@com_github_msgpack_msgpack//:msgpack",
"@com_github_openssl_openssl//:openssl",
"@com_github_uscilab_cereal//:cereal",
":pcie",
"compiler",
],
"//conditions:default":[],
}),

defines = select({
"use_leichi":["APPLY_LEICHI"],
"//conditions:default":[],
})
)


yacl_cc_library(
name = "pcie",
srcs = ["pcie/pcie.cc"],
hdrs = ["pcie/pcie.h"],
deps = [

],
)

yacl_cc_library(
name = "compiler",
srcs = ["compiler/compiler.cc"],
hdrs = ["compiler/compiler.h"],
deps = [

],
)

yacl_cc_test(
name = "key_generator_test",
srcs = select({
":use_leichi":[
"key_generator_test.cc"],
"//conditions:default":[],
}),
deps = select({
":use_leichi":[
":leichi_paillier",
"@com_github_openssl_openssl//:openssl"],
"//conditions:default":[],
}),

defines = select({
"use_leichi":["APPLY_LEICHI"],
"//conditions:default":[],
})
)

yacl_cc_test(
name = "leichi_test",
srcs = select({
":use_leichi":[
"leichi_test.cc"],
"//conditions:default":[],
}),

deps = select({
":use_leichi":[
":leichi_paillier"],
"//conditions:default":[],
}),
defines = select({
"use_leichi":["APPLY_LEICHI"],
"//conditions:default":[],
})
)
38 changes: 38 additions & 0 deletions heu/library/algorithms/leichi_paillier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 使用方法

## 简介
usafchn marked this conversation as resolved.
Show resolved Hide resolved
```
Leichi 隐私计算加速板卡是北极熊芯在隐私计算场景下的第一款高性能产品,针对于隐私计算加密场景中的复杂模运算进行加速。在协议级别上支持 Paillier、RSA 等,在算子级别上支持模乘、模幂、模逆、模加和卷积,最大密文位宽为4096比特。主要适用场景:Paillier、 RSA、联邦学习、机器学习等。

leichi_paillier 默认关闭;
```
## HEU编译

bazel build heu/...
```
bazel test heu/... --test_output=all --cache_test_results=no

使用 leichi_paillier
```
bazel test heu/... --test_output=all --cache_test_results=no --define enable_leichi=true


## leichi_paillier相关单元测试

使用 leichi_paillier
```
bazel test --test_output=all --cache_test_results=no heu/library/algorithms/leichi_paillier:encryptor_test --define enable_leichi=true
bazel test --test_output=all --cache_test_results=no heu/library/algorithms/leichi_paillier:key_generator_test --define enable_leichi=true

```
## Benchmark测试

使用 leichi_paillier
```
scalar 场景性能测试
```
bazel run -c opt heu/library/benchmark:phe -- --schema=Leichi --define enable_leichi=true

vector 场景性能测试
```
bazel run -c opt heu/library/benchmark:np -- --schema=Leichi --define enable_leichi=true
69 changes: 69 additions & 0 deletions heu/library/algorithms/leichi_paillier/ciphertext.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2023 Polar Bear Tech (Xi 'an) 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.

#include "heu/library/algorithms/leichi_paillier/ciphertext.h"
#include <string_view>

namespace heu::lib::algorithms::leichi_paillier {

std::string Ciphertext::ToString() const {
char* str = BN_bn2dec(bn_);
std::string result(str);
return result;
}

Ciphertext& Ciphertext::operator=(const Ciphertext& other) {
if (this != &other) {
BN_copy(bn_, other.bn_);
}
return *this;
}

std::ostream &operator<<(std::ostream &os, const Ciphertext &ct) {
char* str = BN_bn2dec(ct.bn_);
os << str;
return os;
}

bool Ciphertext::operator==(const Ciphertext &other) const {
return (BN_cmp(bn_, other.bn_) == 0)?true:false;
}

bool Ciphertext::operator!=(const Ciphertext &other) const {
return (BN_cmp(bn_, other.bn_) == 0)?true:false;
}

yacl::Buffer Ciphertext::Serialize() const{
uint32_t n_bits_len = BN_num_bits(bn_);
uint8_t* n_arr = new uint8_t[n_bits_len];
std::vector<uint8_t> vec_tmp;
BN_bn2bin(bn_, n_arr);
uint32_t bytes_len = std::ceil(n_bits_len/8.0);
for(uint32_t i=0;i<bytes_len;i++)
{
vec_tmp.push_back(n_arr[i]);
}
uint8_t sign = BN_is_negative(bn_) ? 1 : 0;
vec_tmp.push_back(sign);
yacl::Buffer buf(vec_tmp.data(), std::ceil(BN_num_bits(bn_)/8.0)+1);
return buf;
}
void Ciphertext::Deserialize(yacl::ByteContainerView in){
std::istringstream is((std::string)in);
BN_bin2bn((uint8_t *)(is.str().data()), is.str().size()-1,bn_);
int sign = in[is.str().size()-1]& 0x01 ? 1 : 0;
BN_set_negative(bn_,sign);
}

} // namespace heu::lib::algorithms::leichi_paillier
43 changes: 43 additions & 0 deletions heu/library/algorithms/leichi_paillier/ciphertext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2023 Polar Bear Tech (Xi 'an) 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.

#include "openssl/bn.h"
#include <ostream>
#include <string>
#include <utility>
#include "yacl/base/byte_container_view.h"
#include "cereal/archives/portable_binary.hpp"
#include <vector>
#pragma once
namespace heu::lib::algorithms::leichi_paillier {
class Ciphertext {
public:
BIGNUM* bn_;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

直接使用裸指针是非常危险的,更何况还是 public 字段,可以考虑用只能指针包一下,下面的 Plaintext class 同理。

struct BIGNUM_DELETER {
 public:
  void operator()(BIGNUM* x) { BN_free(x); }
};
using BIGNUM_PTR = std::unique_ptr<BIGNUM, BIGNUM_DELETER>;

public:
Ciphertext() {bn_ = BN_new();}
~Ciphertext(){BN_free(bn_);}
Ciphertext(const Ciphertext& other) {bn_ = BN_dup(other.bn_);}

explicit Ciphertext(BIGNUM *bn){ bn_ = bn;}
std::string ToString() const;
friend std::ostream &operator<<(std::ostream &os, const Ciphertext &ct);

Ciphertext& operator=(const Ciphertext& other);
bool operator==(const Ciphertext &other) const;
bool operator!=(const Ciphertext &other) const;

yacl::Buffer Serialize() const;
void Deserialize(yacl::ByteContainerView in);
};
}// namespace heu::lib::algorithms::leichi_paillier
Loading
Loading