Skip to content
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
113 changes: 113 additions & 0 deletions heu/library/algorithms/ashe/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# 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.

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

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

test_suite(
name = "ashe_tests",
)

yacl_cc_library(
name = "ashe",
hdrs = [
"ashe.h",
],
deps = [
":decryptor",
":encryptor",
":evaluator",
":key_generator",
],
)

yacl_cc_library(
name = "ciphertext",
hdrs = ["ciphertext.h"],
deps = [
"//heu/library/algorithms/util",
"@msgpack-c//:msgpack",
],
)

yacl_cc_library(
name = "secret_key",
hdrs = ["secret_key.h"],
deps = [
"//heu/library/algorithms/util",
"@msgpack-c//:msgpack",
],
)

yacl_cc_library(
name = "public_parameters",
srcs = ["public_parameters.cc"],
hdrs = ["public_parameters.h"],
deps = [
"//heu/library/algorithms/util",
"@msgpack-c//:msgpack",
],
)

yacl_cc_library(
name = "key_generator",
srcs = ["key_generator.cc"],
hdrs = ["key_generator.h"],
deps = [
":encryptor",
":public_parameters",
":secret_key",
],
)

yacl_cc_library(
name = "encryptor",
srcs = ["encryptor.cc"],
hdrs = ["encryptor.h"],
deps = [
":ciphertext",
":public_parameters",
":secret_key",
],
)

yacl_cc_library(
name = "decryptor",
srcs = ["decryptor.cc"],
hdrs = ["decryptor.h"],
deps = [
":ciphertext",
":public_parameters",
":secret_key",
],
)

yacl_cc_library(
name = "evaluator",
srcs = ["evaluator.cc"],
hdrs = ["evaluator.h"],
deps = [
":ciphertext",
":public_parameters",
],
)

yacl_cc_test(
name = "ashe_test",
srcs = ["ashe_tests.cc"],
deps = [
":ashe",
],
)
22 changes: 22 additions & 0 deletions heu/library/algorithms/ashe/ashe.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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.

#pragma once

#include "heu/library/algorithms/ashe/decryptor.h"
#include "heu/library/algorithms/ashe/encryptor.h"
#include "heu/library/algorithms/ashe/evaluator.h"
#include "heu/library/algorithms/ashe/key_generator.h"
#include "heu/library/algorithms/ashe/public_parameters.h"
#include "heu/library/algorithms/ashe/secret_key.h"
174 changes: 174 additions & 0 deletions heu/library/algorithms/ashe/ashe_tests.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// 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.

#include <string>

#include "gtest/gtest.h"

#include "heu/library/algorithms/ashe/ashe.h"

namespace heu::lib::algorithms::ashe::test {

class asheTest : public testing::Test {
protected:
static void SetUpTestSuite() { KeyGenerator::Generate(4096, &sk_, &pp_); }

static SecretKey sk_;
static PublicParameters pp_;
};

SecretKey asheTest::sk_;
PublicParameters asheTest::pp_;

TEST_F(asheTest, SerializeTest) {
auto pp_buffer = pp_.Serialize();
PublicParameters pp2;
pp2.Deserialize(pp_buffer);
ASSERT_EQ(pp_.k_r1, pp2.k_r1);
ASSERT_EQ(pp_.k_r2, pp2.k_r2);
ASSERT_EQ(pp_.k_q, pp2.k_q);
ASSERT_EQ(pp_.k_p, pp2.k_p);
ASSERT_EQ(pp_.randomZeros, pp2.randomZeros);

auto sk_buffer = sk_.Serialize();
SecretKey sk2;
sk2.Deserialize(sk_buffer);
ASSERT_EQ(sk_.p_, sk2.p_);
ASSERT_EQ(sk_.q_, sk2.q_);

Encryptor encryptor(pp2, sk2);

Evaluator evaluator(pp2);

BigInt m0(-12345);
Ciphertext ct = encryptor.Encrypt(m0);

BigInt dc;
Decryptor decryptor(pp_, sk_);
decryptor.Decrypt(ct, &dc);
EXPECT_EQ(dc, m0);
}

TEST_F(asheTest, OperationEvaluate) {
Encryptor encryptor_(pp_, sk_);
Evaluator evaluator_(pp_);
Decryptor decryptor_(pp_, sk_);

Plaintext m0 = Plaintext(12345);
Plaintext m1 = Plaintext(-20000);
Plaintext m3 = Plaintext(0);
Ciphertext c0 = encryptor_.Encrypt(m0);
Ciphertext c1 = encryptor_.Encrypt(m1);
Ciphertext c2 = encryptor_.Encrypt(-m0);
Ciphertext c3 = encryptor_.Encrypt(m3);
EXPECT_EQ(m0, Plaintext(12345));

Plaintext plain;
Ciphertext res;

// evaluate add
res = evaluator_.Add(c0, c0);
decryptor_.Decrypt(res, &plain);
EXPECT_EQ(plain, Plaintext(12345 * 2));
res = evaluator_.Add(c1, c1);
decryptor_.Decrypt(res, &plain);
EXPECT_EQ(plain, Plaintext(-20000 * 2));
res = evaluator_.Add(c0, c1);
decryptor_.Decrypt(res, &plain);
EXPECT_EQ(plain, Plaintext(12345 - 20000));
res = evaluator_.Add(c1, m3);
decryptor_.Decrypt(res, &plain);
EXPECT_EQ(plain, Plaintext(-20000));
res = evaluator_.Add(c0, m1);
decryptor_.Decrypt(res, &plain);
EXPECT_EQ(plain, Plaintext(12345 - 20000));
res = evaluator_.Add(c1, m0);
decryptor_.Decrypt(res, &plain);
EXPECT_EQ(plain, Plaintext(12345 - 20000));
res = evaluator_.Add(c2, c0);
decryptor_.Decrypt(res, &plain);
EXPECT_EQ(plain, Plaintext(0));

res = evaluator_.Mul(c0, m0);
decryptor_.Decrypt(res, &plain);
EXPECT_EQ(plain, Plaintext(12345 * 12345));
res = evaluator_.Mul(c1, m0);
decryptor_.Decrypt(res, &plain);

Ciphertext Zero = encryptor_.EncryptZero();
decryptor_.Decrypt(Zero, &plain);
EXPECT_EQ(plain, BigInt(0));
decryptor_.Decrypt(c1, &plain);
EXPECT_EQ(plain, BigInt(-20000));

Plaintext pt0 = Plaintext(12345);
Plaintext pt1 = Plaintext(20000);
Ciphertext ct0 = encryptor_.Encrypt(pt0);
Ciphertext ct1 = encryptor_.Encrypt(pt1);
evaluator_.AddInplace(&ct0, pt1);
decryptor_.Decrypt(ct0, &plain);
EXPECT_EQ(plain, BigInt(20000 + 12345));
evaluator_.AddInplace(&ct0, ct1);
decryptor_.Decrypt(ct0, &plain);
EXPECT_EQ(plain, BigInt(20000 + 12345 + 20000));
evaluator_.Randomize(&ct0);
decryptor_.Decrypt(ct0, &plain);
EXPECT_EQ(plain, BigInt(20000 + 12345 + 20000));
Plaintext pt_min = Plaintext(pp_.MessageSpace().first);
Plaintext pt_max = Plaintext(pp_.MessageSpace().second - BigInt(1));
Ciphertext ct_max = encryptor_.Encrypt(pt_max);
Ciphertext ct_min = encryptor_.Encrypt(pt_min);
Plaintext tmp = decryptor_.Decrypt(ct_min);
EXPECT_EQ(tmp, pt_min);
tmp = decryptor_.Decrypt(ct_max);
EXPECT_EQ(tmp, pt_max);
}

TEST_F(asheTest, NegateEvalutate) {
Encryptor encryptor_(pp_, sk_);
Evaluator evaluator_(pp_);
Decryptor decryptor_(pp_, sk_);
Plaintext p = Plaintext(123456);
}

TEST_F(asheTest, RuntimeEfficientTest) {
Encryptor encryptor_(pp_, sk_);
Evaluator evaluator_(pp_);
Decryptor decryptor_(pp_, sk_);
Ciphertext c1, c2;
std::chrono::time_point<std::chrono::high_resolution_clock> t1, t2;
t1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; i++) {
c1 = encryptor_.Encrypt(BigInt(123456));
}
t2 = std::chrono::high_resolution_clock::now();
auto duration =
std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
std::cout << "encrypt 1w times used " << duration.count() << std::endl;
t1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; i++) {
c2 = evaluator_.Add(c1, c1);
}
t2 = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
std::cout << "add 1w times used " << duration.count() << std::endl;
t1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; i++) {
Plaintext m = decryptor_.Decrypt(c2);
}
t2 = std::chrono::high_resolution_clock::now();
duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
std::cout << "decrypt 1w times used " << duration.count() << std::endl;
}
} // namespace heu::lib::algorithms::ashe::test
45 changes: 45 additions & 0 deletions heu/library/algorithms/ashe/ciphertext.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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.

#pragma once

#include <utility>

#include "heu/library/algorithms/util/big_int.h"
#include "heu/library/algorithms/util/he_object.h"

namespace heu::lib::algorithms::ashe {
using Plaintext = BigInt;

class Ciphertext : public HeObject<Ciphertext> {
public:
Ciphertext() = default;

explicit Ciphertext(BigInt n) : n_(std::move(n)) {}

[[nodiscard]] std::string ToString() const override {
return fmt::format("CT: {}", n_);
}

bool operator==(const Ciphertext &other) const { return n_ == other.n_; }

bool operator!=(const Ciphertext &other) const {
return !this->operator==(other);
}

MSGPACK_DEFINE(n_);

BigInt n_;
};
} // namespace heu::lib::algorithms::ashe
26 changes: 26 additions & 0 deletions heu/library/algorithms/ashe/decryptor.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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.

#include "heu/library/algorithms/ashe/decryptor.h"

namespace heu::lib::algorithms::ashe {
void Decryptor::Decrypt(const Ciphertext &ct, Plaintext *out) const {
*out = Decrypt(ct);
}

Plaintext Decryptor::Decrypt(const Ciphertext &ct) const {
BigInt tmp = ct.n_.AddMod(ZERO, p).AddMod(ZERO, q).AddMod(ZERO, MAX);
return tmp <= half ? tmp : tmp - MAX;
}
} // namespace heu::lib::algorithms::ashe
Loading
Loading