From 3462066e4aa00de6be5771055ac67bb196f7b222 Mon Sep 17 00:00:00 2001 From: Alec-xdu <1767162258@qq.com> Date: Fri, 16 Jan 2026 20:42:39 +0800 Subject: [PATCH 1/9] add ashe --- heu/library/algorithms/ashe/BUILD.bazel | 113 +++++++++++ heu/library/algorithms/ashe/ashe.h | 22 +++ heu/library/algorithms/ashe/ashe_tests.cc | 183 ++++++++++++++++++ heu/library/algorithms/ashe/ciphertext.h | 50 +++++ heu/library/algorithms/ashe/decryptor.cc | 26 +++ heu/library/algorithms/ashe/decryptor.h | 45 +++++ heu/library/algorithms/ashe/encryptor.cc | 54 ++++++ heu/library/algorithms/ashe/encryptor.h | 46 +++++ heu/library/algorithms/ashe/evaluator.cc | 115 +++++++++++ heu/library/algorithms/ashe/evaluator.h | 65 +++++++ heu/library/algorithms/ashe/key_generator.cc | 58 ++++++ heu/library/algorithms/ashe/key_generator.h | 32 +++ .../algorithms/ashe/public_parameters.cc | 35 ++++ .../algorithms/ashe/public_parameters.h | 81 ++++++++ heu/library/algorithms/ashe/secret_key.h | 49 +++++ 15 files changed, 974 insertions(+) create mode 100644 heu/library/algorithms/ashe/BUILD.bazel create mode 100644 heu/library/algorithms/ashe/ashe.h create mode 100644 heu/library/algorithms/ashe/ashe_tests.cc create mode 100644 heu/library/algorithms/ashe/ciphertext.h create mode 100644 heu/library/algorithms/ashe/decryptor.cc create mode 100644 heu/library/algorithms/ashe/decryptor.h create mode 100644 heu/library/algorithms/ashe/encryptor.cc create mode 100644 heu/library/algorithms/ashe/encryptor.h create mode 100644 heu/library/algorithms/ashe/evaluator.cc create mode 100644 heu/library/algorithms/ashe/evaluator.h create mode 100644 heu/library/algorithms/ashe/key_generator.cc create mode 100644 heu/library/algorithms/ashe/key_generator.h create mode 100644 heu/library/algorithms/ashe/public_parameters.cc create mode 100644 heu/library/algorithms/ashe/public_parameters.h create mode 100644 heu/library/algorithms/ashe/secret_key.h diff --git a/heu/library/algorithms/ashe/BUILD.bazel b/heu/library/algorithms/ashe/BUILD.bazel new file mode 100644 index 0000000..c2f39d4 --- /dev/null +++ b/heu/library/algorithms/ashe/BUILD.bazel @@ -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 = [ + ":public_parameters", + ":secret_key", + ":encryptor" + ], +) + +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" + ] +) \ No newline at end of file diff --git a/heu/library/algorithms/ashe/ashe.h b/heu/library/algorithms/ashe/ashe.h new file mode 100644 index 0000000..052b6b5 --- /dev/null +++ b/heu/library/algorithms/ashe/ashe.h @@ -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" diff --git a/heu/library/algorithms/ashe/ashe_tests.cc b/heu/library/algorithms/ashe/ashe_tests.cc new file mode 100644 index 0000000..577ebca --- /dev/null +++ b/heu/library/algorithms/ashe/ashe_tests.cc @@ -0,0 +1,183 @@ +// 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/ashe.h" + +#include + +#include "gtest/gtest.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); + // EXPECT_EQ(plain, Plaintext(-20000 * 12345)); + // res = evaluator_.Mul(c1, m1); + // decryptor_.Decrypt(res, &plain); + // EXPECT_EQ(plain, Plaintext(20000 * 20000)); + + Ciphertext Zero = encryptor_.EncryptZero(); + decryptor_.Decrypt(Zero, &plain); + EXPECT_EQ(plain, BigInt(0)); + decryptor_.Decrypt(c1, &plain); + EXPECT_EQ(plain, BigInt(-20000)); + + // evaluator_.MulInplace(&c0, m1); + // decryptor_.Decrypt(c0, &plain); + // EXPECT_EQ(plain, BigInt(-20000 * 12345)); + + Plaintext pt0 = Plaintext(12345); + Plaintext pt1 = Plaintext(20000); + Ciphertext ct0 = encryptor_.Encrypt(pt0); + Ciphertext ct1 = encryptor_.Encrypt(pt1); + evaluator_.AddInplace(&ct0, pt1); // call add, test Inplace function + 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)); + // m < pp_.MessageSpace()[1] && m >= pp_.MessageSpace()[0] + 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 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(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(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(t2 - t1); + std:: cout << "decrypt 1w times used " << duration.count() << std::endl; +} +} // namespace heu::lib::algorithms::ou::test diff --git a/heu/library/algorithms/ashe/ciphertext.h b/heu/library/algorithms/ashe/ciphertext.h new file mode 100644 index 0000000..0bb55d2 --- /dev/null +++ b/heu/library/algorithms/ashe/ciphertext.h @@ -0,0 +1,50 @@ +// 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 + +#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 { + 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 diff --git a/heu/library/algorithms/ashe/decryptor.cc b/heu/library/algorithms/ashe/decryptor.cc new file mode 100644 index 0000000..63f360f --- /dev/null +++ b/heu/library/algorithms/ashe/decryptor.cc @@ -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 diff --git a/heu/library/algorithms/ashe/decryptor.h b/heu/library/algorithms/ashe/decryptor.h new file mode 100644 index 0000000..7de265a --- /dev/null +++ b/heu/library/algorithms/ashe/decryptor.h @@ -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 + +#include "heu/library/algorithms/ashe/ciphertext.h" +#include "heu/library/algorithms/ashe/public_parameters.h" +#include "heu/library/algorithms/ashe/secret_key.h" + +namespace heu::lib::algorithms::ashe { +class Decryptor { +public: + explicit Decryptor(PublicParameters pp, SecretKey sk) + : pp_(std::move(pp)), sk_(std::move(sk)) { + p = sk_.p_; + q = sk_.q_; + } + + void Decrypt(const Ciphertext &ct, Plaintext *out) const; + + [[nodiscard]] Plaintext Decrypt(const Ciphertext &ct) const; + +private: + PublicParameters pp_; + SecretKey sk_; + BigInt half = BigInt(UINT64_MAX) / BigInt(2); + BigInt MAX = BigInt(UINT64_MAX); + BigInt p; + BigInt q; + BigInt ZERO = BigInt(0); +}; +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/encryptor.cc b/heu/library/algorithms/ashe/encryptor.cc new file mode 100644 index 0000000..05fc19f --- /dev/null +++ b/heu/library/algorithms/ashe/encryptor.cc @@ -0,0 +1,54 @@ +// 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/encryptor.h" + +namespace heu::lib::algorithms::ashe { +Ciphertext Encryptor::EncryptZero() const { + return Encrypt(BigInt(0)); +} + +Ciphertext Encryptor::Encrypt(const Plaintext &m) const { + return EncryptImpl(m, nullptr); +} + +void Encryptor::Encrypt(const Plaintext &m, Ciphertext *out) const { + *out = Encrypt(m); +} + +std::pair Encryptor::EncryptWithAudit(const Plaintext &m) const { + std::string audit_out; + Ciphertext ct_out = EncryptImpl(m, &audit_out); + audit_out.append( + fmt::format("pt:{}\n ct:{}", m.ToString(), ct_out.n_.ToString())); + return std::make_pair(ct_out, audit_out); +} + +template +Ciphertext Encryptor::EncryptImpl(const Plaintext &m, std::string *audit_str) const { + YACL_ENFORCE(m <= pp_.MessageSpace().second && m >= pp_.MessageSpace().first, + "Plaintext {} is too large, cannot encrypt.", m); + BigInt r, r1; + BigInt::RandomExactBits(pp_.k_r1, &r); + BigInt::RandomExactBits(pp_.k_r2, &r1); + const BigInt m1 = r * sk_.p_ + r1 * sk_.q_ + m.AddMod(ZERO, MAX); + + if constexpr (audit) { + YACL_ENFORCE(audit_str != nullptr); + *audit_str = + fmt::format("r:{}\n r':{}\n", r.ToHexString(), r1.ToHexString()); + } + return Ciphertext(m1); +} +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/encryptor.h b/heu/library/algorithms/ashe/encryptor.h new file mode 100644 index 0000000..5f3ac42 --- /dev/null +++ b/heu/library/algorithms/ashe/encryptor.h @@ -0,0 +1,46 @@ +// 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 + +#include "heu/library/algorithms/ashe/ciphertext.h" +#include "heu/library/algorithms/ashe/public_parameters.h" +#include "heu/library/algorithms/ashe/secret_key.h" + +namespace heu::lib::algorithms::ashe { +class Encryptor { +public: + explicit Encryptor(PublicParameters pk, SecretKey sk) + : pp_(std::move(pk)), sk_(std::move(sk)) {} + + [[nodiscard]] Ciphertext EncryptZero() const; + [[nodiscard]] Ciphertext Encrypt(const Plaintext &m) const; + + void Encrypt(const Plaintext &m, Ciphertext *out) const; + + [[nodiscard]] std::pair EncryptWithAudit( + const Plaintext &m) const; + +private: + template + Ciphertext EncryptImpl(const Plaintext &m, + std::string *audit_str) const; + PublicParameters pp_; + SecretKey sk_; + BigInt ZERO = BigInt(0); + BigInt MAX = BigInt(UINT64_MAX); +}; +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/evaluator.cc b/heu/library/algorithms/ashe/evaluator.cc new file mode 100644 index 0000000..ed91534 --- /dev/null +++ b/heu/library/algorithms/ashe/evaluator.cc @@ -0,0 +1,115 @@ +// 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/evaluator.h" + +#include "fmt/ranges.h" + +namespace heu::lib::algorithms::ashe { +void Evaluator::Randomize(Ciphertext *ct) const { + BigInt r; + BigInt::RandomLtN(BigInt(pp_.randomZeros.size()), &r); + AddInplace(ct, Ciphertext(pp_.randomZeros[r.Get()])); +} + +Ciphertext Evaluator::Add(const Ciphertext &a, const Ciphertext &b) const { + return Ciphertext(a.n_ + b.n_); +} + +Ciphertext Evaluator::Add(const Ciphertext &a, const Plaintext &b) const { + return Ciphertext(a.n_ + b % MAX); +} + +Ciphertext Evaluator::Add(const Plaintext &a, const Ciphertext &b) const { + return Add(b, a); +} + +Plaintext Evaluator::Add(const Plaintext &a, const Plaintext &b) const { + return a + b; +} + +void Evaluator::AddInplace(Ciphertext *a, const Ciphertext &b) const { + *a = Add(*a, b); +} + +void Evaluator::AddInplace(Ciphertext *a, const Plaintext &b) const { + *a = Add(*a, b); +} + +void Evaluator::AddInplace(Plaintext *a, const Plaintext &b) const { + *a = Add(*a, b); +} + +Ciphertext Evaluator::Sub(const Ciphertext &a, const Ciphertext &b) const { + const Ciphertext b_ = Negate(b); + return Add(a, b_); +} + +Ciphertext Evaluator::Sub(const Ciphertext &a, const Plaintext &b) const { + return Add(a, -b); +} + +Ciphertext Evaluator::Sub(const Plaintext &a, const Ciphertext &b) const { + return Add(Negate(b), a); +} + +Plaintext Evaluator::Sub(const Plaintext &a, const Plaintext &b) const { + return a - b; +} + +void Evaluator::SubInplace(Ciphertext *a, const Ciphertext &b) const { + *a = Sub(*a, b); +} + +void Evaluator::SubInplace(Ciphertext *a, const Plaintext &p) const { + *a = Sub(*a, p); +} + +void Evaluator::SubInplace(Plaintext *a, const Plaintext &b) const { + *a = Sub(*a, b); +} + +Ciphertext Evaluator::Mul(const Ciphertext &a, const Plaintext &b) const { + YACL_ENFORCE(b % MAX <= BigInt(2).Pow(16), + "Plaintext {} is too large, cannot encrypt.", b); + Ciphertext res; + res.n_ = b.AddMod(ZERO, MAX) * a.n_; + return res; +} + +Ciphertext Evaluator::Mul(const Plaintext &a, const Ciphertext &b) const { + return Mul(b, a); +} + +Plaintext Evaluator::Mul(const Plaintext &a, const Plaintext &b) const { + return a * b; +} + +void Evaluator::MulInplace(Ciphertext *a, const Plaintext &b) const { + *a = Mul(*a, b); +} + +void Evaluator::MulInplace(Plaintext *a, const Plaintext &b) const { + *a = Mul(*a, b); +} + +Ciphertext Evaluator::Negate(const Ciphertext &a) const { + const BigInt neg = BigInt(-1) % MAX; + return Mul(a, neg); +} + +void Evaluator::NegateInplace(Ciphertext *a) const { + *a = Negate(*a); +} +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/evaluator.h b/heu/library/algorithms/ashe/evaluator.h new file mode 100644 index 0000000..9670bb3 --- /dev/null +++ b/heu/library/algorithms/ashe/evaluator.h @@ -0,0 +1,65 @@ +// 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 + +#include "heu/library/algorithms/ashe/ciphertext.h" +#include "heu/library/algorithms/ashe/public_parameters.h" + +namespace heu::lib::algorithms::ashe { +class Evaluator { +public: + explicit Evaluator(PublicParameters pp) : pp_(std::move(pp)) { + } + + void Randomize(Ciphertext *ct) const; + + [[nodiscard]] Ciphertext Add(const Ciphertext &a, const Ciphertext &b) const; + [[nodiscard]] Ciphertext Add(const Ciphertext &a, const Plaintext &b) const; + [[nodiscard]] Ciphertext Add(const Plaintext &a, const Ciphertext &b) const; + [[nodiscard]] Plaintext Add(const Plaintext &a, const Plaintext &b) const; + + void AddInplace(Ciphertext *a, const Ciphertext &b) const; + void AddInplace(Ciphertext *a, const Plaintext &b) const; + void AddInplace(Plaintext *a, const Plaintext &b) const; + + [[nodiscard]] Ciphertext Sub(const Ciphertext &a, const Ciphertext &b) const; + [[nodiscard]] Ciphertext Sub(const Ciphertext &a, const Plaintext &b) const; + [[nodiscard]] Ciphertext Sub(const Plaintext &a, const Ciphertext &b) const; + [[nodiscard]] Plaintext Sub(const Plaintext &a, const Plaintext &b) const; + + void SubInplace(Ciphertext *a, const Ciphertext &b) const; + void SubInplace(Ciphertext *a, const Plaintext &p) const; + void SubInplace(Plaintext *a, const Plaintext &b) const; + + [[nodiscard]] Ciphertext Mul(const Ciphertext &a, const Plaintext &b) const; + [[nodiscard]] Ciphertext Mul(const Plaintext &a, const Ciphertext &b) const; + [[nodiscard]] Plaintext Mul(const Plaintext &a, const Plaintext &b) const; + + void MulInplace(Ciphertext *a, const Plaintext &b) const; + void MulInplace(Plaintext *a, const Plaintext &b) const; + + [[nodiscard]] Ciphertext Negate(const Ciphertext &a) const; + void NegateInplace(Ciphertext *a) const; + +private: + PublicParameters pp_; + BigInt ONE = BigInt(1); + BigInt ZERO = BigInt(0); + BigInt MAX = BigInt(UINT64_MAX); + BigInt PlainSpace = BigInt(2).Pow(16); +}; +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/key_generator.cc b/heu/library/algorithms/ashe/key_generator.cc new file mode 100644 index 0000000..cfacc9e --- /dev/null +++ b/heu/library/algorithms/ashe/key_generator.cc @@ -0,0 +1,58 @@ +// 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/key_generator.h" + +#include + +namespace heu::lib::algorithms::ashe { +void KeyGenerator::Generate(int key_size, SecretKey *sk, PublicParameters *pk) { + int64_t k_r1, k_p, k_q, k_r2, k_m;; + if (key_size == 2048) { + k_r1 = 4384; + k_p = 1536; + k_q = 1008; + k_r2 = 512; + k_m = 64; + } else { + k_r1 = 8832; + k_p = 1536; + k_q = 992; + k_r2 = 512; + k_m = 64; + } + std::vector zeros; + BigInt p = BigInt::RandPrimeOver(k_p); + const BigInt q = BigInt::RandPrimeOver(k_q); + *sk = SecretKey(p, q); + + InitZeros(k_r1, k_p, k_q, k_r2, k_m, *sk, &zeros); + *pk = + PublicParameters(k_r1, k_p, k_q, k_r2, k_m, zeros); +} + +void KeyGenerator::Generate(SecretKey *sk, PublicParameters *pk) { + Generate(2048, sk, pk); +} + +void KeyGenerator::InitZeros(int64_t k_r1, int64_t k_p, int64_t k_q, + int64_t k_r2, int64_t k_m, SecretKey sk_, + std::vector *zeros) { + auto tmp = PublicParameters(k_r1, k_p, k_q, k_r2, k_m); + auto et = Encryptor(tmp, std::move(sk_)); + for (int i = 1; i <= 20; ++i) { + zeros->emplace_back(et.Encrypt(BigInt(0)).n_); + } +} +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/key_generator.h b/heu/library/algorithms/ashe/key_generator.h new file mode 100644 index 0000000..54c8c5f --- /dev/null +++ b/heu/library/algorithms/ashe/key_generator.h @@ -0,0 +1,32 @@ +// 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/public_parameters.h" +#include "heu/library/algorithms/ashe/secret_key.h" +#include "heu/library/algorithms/ashe/encryptor.h" + +namespace heu::lib::algorithms::ashe { +class KeyGenerator { +public: + static void Generate(int key_size, SecretKey *sk, PublicParameters *pk); + static void Generate(SecretKey *sk, PublicParameters *pk); + +private: + static void InitZeros(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, + int64_t k_m, SecretKey sk_, + std::vector *zeros); +}; +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/public_parameters.cc b/heu/library/algorithms/ashe/public_parameters.cc new file mode 100644 index 0000000..f81f85b --- /dev/null +++ b/heu/library/algorithms/ashe/public_parameters.cc @@ -0,0 +1,35 @@ +#include "heu/library/algorithms/ashe/public_parameters.h" + +namespace heu::lib::algorithms::ashe { +PublicParameters::PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, + int64_t k_r2, int64_t k_m) { + this->k_r1 = k_r1; + this->k_p = k_p; + this->k_q = k_q; + this->k_r2 = k_r2; + this->k_m = k_m; + Init(); +} + +PublicParameters::PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, + int64_t k_r2, int64_t k_m, + const std::vector &zeros) : + PublicParameters( + k_r1, k_p, k_q, k_r2, k_m) { + this->randomZeros = zeros; +} + +std::string PublicParameters::ToString() const { + return fmt::format( + "ashe PP: k_r1={}, k_p={}, k_q={}, " + "k_r2={}, k_m={}, randomZeros={}[size:{}]", + std::to_string(k_r1), std::to_string(k_p), std::to_string(k_q), + std::to_string(k_r2), std::to_string(k_m), ToHexString(randomZeros), + randomZeros.size()); +} + +void PublicParameters::Init() { + this->M[1] = BigInt(2).Pow(k_m - 1) - BigInt(1); + this->M[0] = -this->M[1]; +} +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/public_parameters.h b/heu/library/algorithms/ashe/public_parameters.h new file mode 100644 index 0000000..b71f4ec --- /dev/null +++ b/heu/library/algorithms/ashe/public_parameters.h @@ -0,0 +1,81 @@ +// 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 + +#include "heu/library/algorithms/util/big_int.h" +#include "heu/library/algorithms/util/he_object.h" + +namespace heu::lib::algorithms::ashe { +class PublicParameters : public HeObject { +private: + BigInt plaintextBound; + + static std::string ToHexString(const std::vector &vec) { + std::ostringstream oss; + oss << "["; + for (size_t i = 0; i < vec.size(); ++i) { + if (i != 0) { + oss << ", "; + } + oss << "0x" << vec[i].ToHexString(); + } + oss << "]"; + return oss.str(); + } + +public: + int64_t k_r1 = 4384; + int64_t k_p = 1536; + int64_t k_q = 1008; + int64_t k_r2 = 512; + int64_t k_m = 64; + std::vector randomZeros; + BigInt M[2]; + + + PublicParameters() = default; + + PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, + int64_t k_m); + + PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, + int64_t k_m, const std::vector &zeros); + + bool operator==(const PublicParameters &other) const { + return k_r1 == other.k_r1 && k_p == other.k_p && k_q == other.k_q && + k_r2 == other.k_r2 && k_m == other.k_m; + } + + bool operator!=(const PublicParameters &other) const { + return !this->operator==(other); + } + + [[nodiscard]] std::string ToString() const override; + + [[nodiscard]] const BigInt &PlaintextBound() const & { + return M[1]; + } + + void Init(); + + [[nodiscard]] std::pair MessageSpace() const { + return std::make_pair(M[0], M[1]); + } + + MSGPACK_DEFINE(k_r1, k_p, k_q, k_r2, k_m, M, randomZeros); +}; +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/secret_key.h b/heu/library/algorithms/ashe/secret_key.h new file mode 100644 index 0000000..65dff8f --- /dev/null +++ b/heu/library/algorithms/ashe/secret_key.h @@ -0,0 +1,49 @@ +// 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 + +#include "heu/library/algorithms/util/he_object.h" + +namespace heu::lib::algorithms::ashe { +class SecretKey : public HeObject { +public: + BigInt p_, q_; + + SecretKey(BigInt p, BigInt q) { + this->p_ = std::move(p); + this->q_ = std::move(q); + } + + SecretKey() = default; + + bool operator==(const SecretKey &other) const { + return p_ == other.p_ && q_ == other.q_; + } + + bool operator!=(const SecretKey &other) const { + return !this->operator==(other); + } + + [[nodiscard]] std::string ToString() const override { + return fmt::format("ashe SK, p={}[{}bits], q={}[{}bits]", + p_.ToHexString(), p_.BitCount(), + q_.ToHexString(), q_.BitCount()); + } + + MSGPACK_DEFINE(p_, q_); +}; +} // namespace heu::lib::algorithms::ashe From 4371c7c234746811ec036a309eec1d0b84dab4c0 Mon Sep 17 00:00:00 2001 From: Alec-xdu <1767162258@qq.com> Date: Fri, 16 Jan 2026 21:11:13 +0800 Subject: [PATCH 2/9] reformat --- heu/library/algorithms/ashe/BUILD.bazel | 2 +- heu/library/algorithms/ashe/ashe_tests.cc | 35 +++++++------------ heu/library/algorithms/ashe/ciphertext.h | 10 +++--- heu/library/algorithms/ashe/decryptor.cc | 2 +- heu/library/algorithms/ashe/decryptor.h | 8 ++--- heu/library/algorithms/ashe/encryptor.cc | 12 +++---- heu/library/algorithms/ashe/encryptor.h | 11 +++--- heu/library/algorithms/ashe/evaluator.cc | 6 ++-- heu/library/algorithms/ashe/evaluator.h | 9 +++-- heu/library/algorithms/ashe/key_generator.cc | 8 ++--- heu/library/algorithms/ashe/key_generator.h | 11 +++--- .../algorithms/ashe/public_parameters.cc | 7 ++-- .../algorithms/ashe/public_parameters.h | 11 +++--- heu/library/algorithms/ashe/secret_key.h | 9 +++-- 14 files changed, 60 insertions(+), 81 deletions(-) diff --git a/heu/library/algorithms/ashe/BUILD.bazel b/heu/library/algorithms/ashe/BUILD.bazel index c2f39d4..5eb85ee 100644 --- a/heu/library/algorithms/ashe/BUILD.bazel +++ b/heu/library/algorithms/ashe/BUILD.bazel @@ -110,4 +110,4 @@ yacl_cc_test( deps = [ ":ashe" ] -) \ No newline at end of file +) diff --git a/heu/library/algorithms/ashe/ashe_tests.cc b/heu/library/algorithms/ashe/ashe_tests.cc index 577ebca..5036569 100644 --- a/heu/library/algorithms/ashe/ashe_tests.cc +++ b/heu/library/algorithms/ashe/ashe_tests.cc @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "heu/library/algorithms/ashe/ashe.h" - #include #include "gtest/gtest.h" +#include "heu/library/algorithms/ashe/ashe.h" + namespace heu::lib::algorithms::ashe::test { class asheTest : public testing::Test { @@ -27,6 +27,7 @@ class asheTest : public testing::Test { static SecretKey sk_; static PublicParameters pp_; }; + SecretKey asheTest::sk_; PublicParameters asheTest::pp_; @@ -104,10 +105,6 @@ TEST_F(asheTest, OperationEvaluate) { EXPECT_EQ(plain, Plaintext(12345 * 12345)); res = evaluator_.Mul(c1, m0); decryptor_.Decrypt(res, &plain); - // EXPECT_EQ(plain, Plaintext(-20000 * 12345)); - // res = evaluator_.Mul(c1, m1); - // decryptor_.Decrypt(res, &plain); - // EXPECT_EQ(plain, Plaintext(20000 * 20000)); Ciphertext Zero = encryptor_.EncryptZero(); decryptor_.Decrypt(Zero, &plain); @@ -115,15 +112,11 @@ TEST_F(asheTest, OperationEvaluate) { decryptor_.Decrypt(c1, &plain); EXPECT_EQ(plain, BigInt(-20000)); - // evaluator_.MulInplace(&c0, m1); - // decryptor_.Decrypt(c0, &plain); - // EXPECT_EQ(plain, BigInt(-20000 * 12345)); - Plaintext pt0 = Plaintext(12345); Plaintext pt1 = Plaintext(20000); Ciphertext ct0 = encryptor_.Encrypt(pt0); Ciphertext ct1 = encryptor_.Encrypt(pt1); - evaluator_.AddInplace(&ct0, pt1); // call add, test Inplace function + evaluator_.AddInplace(&ct0, pt1); decryptor_.Decrypt(ct0, &plain); EXPECT_EQ(plain, BigInt(20000 + 12345)); evaluator_.AddInplace(&ct0, ct1); @@ -132,7 +125,6 @@ TEST_F(asheTest, OperationEvaluate) { evaluator_.Randomize(&ct0); decryptor_.Decrypt(ct0, &plain); EXPECT_EQ(plain, BigInt(20000 + 12345 + 20000)); - // m < pp_.MessageSpace()[1] && m >= pp_.MessageSpace()[0] Plaintext pt_min = Plaintext(pp_.MessageSpace().first); Plaintext pt_max = Plaintext(pp_.MessageSpace().second - BigInt(1)); Ciphertext ct_max = encryptor_.Encrypt(pt_max); @@ -141,7 +133,6 @@ TEST_F(asheTest, OperationEvaluate) { EXPECT_EQ(tmp, pt_min); tmp = decryptor_.Decrypt(ct_max); EXPECT_EQ(tmp, pt_max); - } TEST_F(asheTest, NegateEvalutate) { @@ -149,7 +140,6 @@ TEST_F(asheTest, NegateEvalutate) { Evaluator evaluator_(pp_); Decryptor decryptor_(pp_, sk_); Plaintext p = Plaintext(123456); - } TEST_F(asheTest, RuntimeEfficientTest) { @@ -159,25 +149,26 @@ TEST_F(asheTest, RuntimeEfficientTest) { Ciphertext c1, c2; std::chrono::time_point t1, t2; t1 = std::chrono::high_resolution_clock::now(); - for (int i = 0 ; i < 10000 ; i++) { + 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(t2 - t1); - std:: cout << "encrypt 1w times used " << duration.count() << std::endl; + auto duration = + std::chrono::duration_cast(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++) { + for (int i = 0; i < 10000; i++) { c2 = evaluator_.Add(c1, c1); } t2 = std::chrono::high_resolution_clock::now(); duration = std::chrono::duration_cast(t2 - t1); - std:: cout << "add 1w times used " << duration.count() << std::endl; + std::cout << "add 1w times used " << duration.count() << std::endl; t1 = std::chrono::high_resolution_clock::now(); - for (int i = 0 ; i < 10000 ; i++) { + for (int i = 0; i < 10000; i++) { Plaintext m = decryptor_.Decrypt(c2); } t2 = std::chrono::high_resolution_clock::now(); duration = std::chrono::duration_cast(t2 - t1); - std:: cout << "decrypt 1w times used " << duration.count() << std::endl; + std::cout << "decrypt 1w times used " << duration.count() << std::endl; } -} // namespace heu::lib::algorithms::ou::test +} // namespace heu::lib::algorithms::ashe::test diff --git a/heu/library/algorithms/ashe/ciphertext.h b/heu/library/algorithms/ashe/ciphertext.h index 0bb55d2..356f789 100644 --- a/heu/library/algorithms/ashe/ciphertext.h +++ b/heu/library/algorithms/ashe/ciphertext.h @@ -20,15 +20,14 @@ #include "heu/library/algorithms/util/he_object.h" namespace heu::lib::algorithms::ashe { - using Plaintext = BigInt; class Ciphertext : public HeObject { - public: - +public: Ciphertext() = default; - explicit Ciphertext(BigInt n) : n_(std::move(n)) {} + explicit Ciphertext(BigInt n) : n_(std::move(n)) { + } [[nodiscard]] std::string ToString() const override { return fmt::format("CT: {}", n_); @@ -46,5 +45,4 @@ class Ciphertext : public HeObject { BigInt n_; }; - -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/decryptor.cc b/heu/library/algorithms/ashe/decryptor.cc index 63f360f..4f17a64 100644 --- a/heu/library/algorithms/ashe/decryptor.cc +++ b/heu/library/algorithms/ashe/decryptor.cc @@ -23,4 +23,4 @@ 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 +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/decryptor.h b/heu/library/algorithms/ashe/decryptor.h index 7de265a..b3ae071 100644 --- a/heu/library/algorithms/ashe/decryptor.h +++ b/heu/library/algorithms/ashe/decryptor.h @@ -22,9 +22,9 @@ namespace heu::lib::algorithms::ashe { class Decryptor { -public: + public: explicit Decryptor(PublicParameters pp, SecretKey sk) - : pp_(std::move(pp)), sk_(std::move(sk)) { + : pp_(std::move(pp)), sk_(std::move(sk)) { p = sk_.p_; q = sk_.q_; } @@ -33,7 +33,7 @@ class Decryptor { [[nodiscard]] Plaintext Decrypt(const Ciphertext &ct) const; -private: + private: PublicParameters pp_; SecretKey sk_; BigInt half = BigInt(UINT64_MAX) / BigInt(2); @@ -42,4 +42,4 @@ class Decryptor { BigInt q; BigInt ZERO = BigInt(0); }; -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/encryptor.cc b/heu/library/algorithms/ashe/encryptor.cc index 05fc19f..4dadc12 100644 --- a/heu/library/algorithms/ashe/encryptor.cc +++ b/heu/library/algorithms/ashe/encryptor.cc @@ -15,9 +15,7 @@ #include "heu/library/algorithms/ashe/encryptor.h" namespace heu::lib::algorithms::ashe { -Ciphertext Encryptor::EncryptZero() const { - return Encrypt(BigInt(0)); -} +Ciphertext Encryptor::EncryptZero() const { return Encrypt(BigInt(0)); } Ciphertext Encryptor::Encrypt(const Plaintext &m) const { return EncryptImpl(m, nullptr); @@ -27,7 +25,8 @@ void Encryptor::Encrypt(const Plaintext &m, Ciphertext *out) const { *out = Encrypt(m); } -std::pair Encryptor::EncryptWithAudit(const Plaintext &m) const { +std::pair Encryptor::EncryptWithAudit( + const Plaintext &m) const { std::string audit_out; Ciphertext ct_out = EncryptImpl(m, &audit_out); audit_out.append( @@ -36,7 +35,8 @@ std::pair Encryptor::EncryptWithAudit(const Plaintext & } template -Ciphertext Encryptor::EncryptImpl(const Plaintext &m, std::string *audit_str) const { +Ciphertext Encryptor::EncryptImpl(const Plaintext &m, + std::string *audit_str) const { YACL_ENFORCE(m <= pp_.MessageSpace().second && m >= pp_.MessageSpace().first, "Plaintext {} is too large, cannot encrypt.", m); BigInt r, r1; @@ -51,4 +51,4 @@ Ciphertext Encryptor::EncryptImpl(const Plaintext &m, std::string *audit_str) co } return Ciphertext(m1); } -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/encryptor.h b/heu/library/algorithms/ashe/encryptor.h index 5f3ac42..d5bf2c4 100644 --- a/heu/library/algorithms/ashe/encryptor.h +++ b/heu/library/algorithms/ashe/encryptor.h @@ -22,9 +22,9 @@ namespace heu::lib::algorithms::ashe { class Encryptor { -public: + public: explicit Encryptor(PublicParameters pk, SecretKey sk) - : pp_(std::move(pk)), sk_(std::move(sk)) {} + : pp_(std::move(pk)), sk_(std::move(sk)) {} [[nodiscard]] Ciphertext EncryptZero() const; [[nodiscard]] Ciphertext Encrypt(const Plaintext &m) const; @@ -34,13 +34,12 @@ class Encryptor { [[nodiscard]] std::pair EncryptWithAudit( const Plaintext &m) const; -private: + private: template - Ciphertext EncryptImpl(const Plaintext &m, - std::string *audit_str) const; + Ciphertext EncryptImpl(const Plaintext &m, std::string *audit_str) const; PublicParameters pp_; SecretKey sk_; BigInt ZERO = BigInt(0); BigInt MAX = BigInt(UINT64_MAX); }; -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/evaluator.cc b/heu/library/algorithms/ashe/evaluator.cc index ed91534..38c4712 100644 --- a/heu/library/algorithms/ashe/evaluator.cc +++ b/heu/library/algorithms/ashe/evaluator.cc @@ -109,7 +109,5 @@ Ciphertext Evaluator::Negate(const Ciphertext &a) const { return Mul(a, neg); } -void Evaluator::NegateInplace(Ciphertext *a) const { - *a = Negate(*a); -} -} // namespace heu::lib::algorithms::ashe +void Evaluator::NegateInplace(Ciphertext *a) const { *a = Negate(*a); } +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/evaluator.h b/heu/library/algorithms/ashe/evaluator.h index 9670bb3..8e85b5b 100644 --- a/heu/library/algorithms/ashe/evaluator.h +++ b/heu/library/algorithms/ashe/evaluator.h @@ -21,9 +21,8 @@ namespace heu::lib::algorithms::ashe { class Evaluator { -public: - explicit Evaluator(PublicParameters pp) : pp_(std::move(pp)) { - } + public: + explicit Evaluator(PublicParameters pp) : pp_(std::move(pp)) {} void Randomize(Ciphertext *ct) const; @@ -55,11 +54,11 @@ class Evaluator { [[nodiscard]] Ciphertext Negate(const Ciphertext &a) const; void NegateInplace(Ciphertext *a) const; -private: + private: PublicParameters pp_; BigInt ONE = BigInt(1); BigInt ZERO = BigInt(0); BigInt MAX = BigInt(UINT64_MAX); BigInt PlainSpace = BigInt(2).Pow(16); }; -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/key_generator.cc b/heu/library/algorithms/ashe/key_generator.cc index cfacc9e..9509494 100644 --- a/heu/library/algorithms/ashe/key_generator.cc +++ b/heu/library/algorithms/ashe/key_generator.cc @@ -18,7 +18,8 @@ namespace heu::lib::algorithms::ashe { void KeyGenerator::Generate(int key_size, SecretKey *sk, PublicParameters *pk) { - int64_t k_r1, k_p, k_q, k_r2, k_m;; + int64_t k_r1, k_p, k_q, k_r2, k_m; + ; if (key_size == 2048) { k_r1 = 4384; k_p = 1536; @@ -38,8 +39,7 @@ void KeyGenerator::Generate(int key_size, SecretKey *sk, PublicParameters *pk) { *sk = SecretKey(p, q); InitZeros(k_r1, k_p, k_q, k_r2, k_m, *sk, &zeros); - *pk = - PublicParameters(k_r1, k_p, k_q, k_r2, k_m, zeros); + *pk = PublicParameters(k_r1, k_p, k_q, k_r2, k_m, zeros); } void KeyGenerator::Generate(SecretKey *sk, PublicParameters *pk) { @@ -55,4 +55,4 @@ void KeyGenerator::InitZeros(int64_t k_r1, int64_t k_p, int64_t k_q, zeros->emplace_back(et.Encrypt(BigInt(0)).n_); } } -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/key_generator.h b/heu/library/algorithms/ashe/key_generator.h index 54c8c5f..4646fdf 100644 --- a/heu/library/algorithms/ashe/key_generator.h +++ b/heu/library/algorithms/ashe/key_generator.h @@ -14,19 +14,18 @@ #pragma once +#include "heu/library/algorithms/ashe/encryptor.h" #include "heu/library/algorithms/ashe/public_parameters.h" #include "heu/library/algorithms/ashe/secret_key.h" -#include "heu/library/algorithms/ashe/encryptor.h" namespace heu::lib::algorithms::ashe { class KeyGenerator { -public: + public: static void Generate(int key_size, SecretKey *sk, PublicParameters *pk); static void Generate(SecretKey *sk, PublicParameters *pk); -private: + private: static void InitZeros(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, - int64_t k_m, SecretKey sk_, - std::vector *zeros); + int64_t k_m, SecretKey sk_, std::vector *zeros); }; -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/public_parameters.cc b/heu/library/algorithms/ashe/public_parameters.cc index f81f85b..2b9a345 100644 --- a/heu/library/algorithms/ashe/public_parameters.cc +++ b/heu/library/algorithms/ashe/public_parameters.cc @@ -13,9 +13,8 @@ PublicParameters::PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, PublicParameters::PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, int64_t k_m, - const std::vector &zeros) : - PublicParameters( - k_r1, k_p, k_q, k_r2, k_m) { + const std::vector &zeros) + : PublicParameters(k_r1, k_p, k_q, k_r2, k_m) { this->randomZeros = zeros; } @@ -32,4 +31,4 @@ void PublicParameters::Init() { this->M[1] = BigInt(2).Pow(k_m - 1) - BigInt(1); this->M[0] = -this->M[1]; } -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/public_parameters.h b/heu/library/algorithms/ashe/public_parameters.h index b71f4ec..b5cc12e 100644 --- a/heu/library/algorithms/ashe/public_parameters.h +++ b/heu/library/algorithms/ashe/public_parameters.h @@ -21,7 +21,7 @@ namespace heu::lib::algorithms::ashe { class PublicParameters : public HeObject { -private: + private: BigInt plaintextBound; static std::string ToHexString(const std::vector &vec) { @@ -37,7 +37,7 @@ class PublicParameters : public HeObject { return oss.str(); } -public: + public: int64_t k_r1 = 4384; int64_t k_p = 1536; int64_t k_q = 1008; @@ -46,7 +46,6 @@ class PublicParameters : public HeObject { std::vector randomZeros; BigInt M[2]; - PublicParameters() = default; PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, @@ -66,9 +65,7 @@ class PublicParameters : public HeObject { [[nodiscard]] std::string ToString() const override; - [[nodiscard]] const BigInt &PlaintextBound() const & { - return M[1]; - } + [[nodiscard]] const BigInt &PlaintextBound() const & { return M[1]; } void Init(); @@ -78,4 +75,4 @@ class PublicParameters : public HeObject { MSGPACK_DEFINE(k_r1, k_p, k_q, k_r2, k_m, M, randomZeros); }; -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/secret_key.h b/heu/library/algorithms/ashe/secret_key.h index 65dff8f..117fe5c 100644 --- a/heu/library/algorithms/ashe/secret_key.h +++ b/heu/library/algorithms/ashe/secret_key.h @@ -20,7 +20,7 @@ namespace heu::lib::algorithms::ashe { class SecretKey : public HeObject { -public: + public: BigInt p_, q_; SecretKey(BigInt p, BigInt q) { @@ -39,11 +39,10 @@ class SecretKey : public HeObject { } [[nodiscard]] std::string ToString() const override { - return fmt::format("ashe SK, p={}[{}bits], q={}[{}bits]", - p_.ToHexString(), p_.BitCount(), - q_.ToHexString(), q_.BitCount()); + return fmt::format("ashe SK, p={}[{}bits], q={}[{}bits]", p_.ToHexString(), + p_.BitCount(), q_.ToHexString(), q_.BitCount()); } MSGPACK_DEFINE(p_, q_); }; -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe From 9db2c2f145b49529810066204df4a062694d495d Mon Sep 17 00:00:00 2001 From: Alec-xdu <1767162258@qq.com> Date: Mon, 19 Jan 2026 14:02:15 +0800 Subject: [PATCH 3/9] reformat --- heu/library/algorithms/ashe/BUILD.bazel | 8 ++++---- heu/library/algorithms/ashe/ciphertext.h | 11 ++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/heu/library/algorithms/ashe/BUILD.bazel b/heu/library/algorithms/ashe/BUILD.bazel index 5eb85ee..a647baf 100644 --- a/heu/library/algorithms/ashe/BUILD.bazel +++ b/heu/library/algorithms/ashe/BUILD.bazel @@ -68,7 +68,7 @@ yacl_cc_library( deps = [ ":public_parameters", ":secret_key", - ":encryptor" + ":encryptor", ], ) @@ -79,7 +79,7 @@ yacl_cc_library( deps = [ ":ciphertext", ":public_parameters", - ":secret_key" + ":secret_key", ], ) @@ -108,6 +108,6 @@ yacl_cc_test( name = "ashe_test", srcs = ["ashe_tests.cc"], deps = [ - ":ashe" - ] + ":ashe", + ], ) diff --git a/heu/library/algorithms/ashe/ciphertext.h b/heu/library/algorithms/ashe/ciphertext.h index 356f789..9668403 100644 --- a/heu/library/algorithms/ashe/ciphertext.h +++ b/heu/library/algorithms/ashe/ciphertext.h @@ -23,19 +23,16 @@ namespace heu::lib::algorithms::ashe { using Plaintext = BigInt; class Ciphertext : public HeObject { -public: + public: Ciphertext() = default; - explicit Ciphertext(BigInt n) : n_(std::move(n)) { - } + 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 n_ == other.n_; } bool operator!=(const Ciphertext &other) const { return !this->operator==(other); @@ -45,4 +42,4 @@ class Ciphertext : public HeObject { BigInt n_; }; -} // namespace heu::lib::algorithms::ashe +} // namespace heu::lib::algorithms::ashe From 2e209845b6abd63a90273509c3bb8dbe99f784af Mon Sep 17 00:00:00 2001 From: Alec-xdu <1767162258@qq.com> Date: Mon, 19 Jan 2026 15:54:43 +0800 Subject: [PATCH 4/9] reformat BUILD.bazel --- heu/library/algorithms/ashe/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/heu/library/algorithms/ashe/BUILD.bazel b/heu/library/algorithms/ashe/BUILD.bazel index a647baf..43bd176 100644 --- a/heu/library/algorithms/ashe/BUILD.bazel +++ b/heu/library/algorithms/ashe/BUILD.bazel @@ -66,9 +66,9 @@ yacl_cc_library( srcs = ["key_generator.cc"], hdrs = ["key_generator.h"], deps = [ + ":encryptor", ":public_parameters", ":secret_key", - ":encryptor", ], ) From 7ecc4a385f0e9be9b8d63a6bad57809f7ab80ede Mon Sep 17 00:00:00 2001 From: Alec-xdu <1767162258@qq.com> Date: Mon, 19 Jan 2026 16:00:48 +0800 Subject: [PATCH 5/9] add license information for public_parameters.cc --- heu/library/algorithms/ashe/public_parameters.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/heu/library/algorithms/ashe/public_parameters.cc b/heu/library/algorithms/ashe/public_parameters.cc index 2b9a345..0610562 100644 --- a/heu/library/algorithms/ashe/public_parameters.cc +++ b/heu/library/algorithms/ashe/public_parameters.cc @@ -1,3 +1,17 @@ +// 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/public_parameters.h" namespace heu::lib::algorithms::ashe { From 3bd7f90871b715dd8af4759b05c7d07354a8ca84 Mon Sep 17 00:00:00 2001 From: mqh <1767162258@qq.com> Date: Fri, 24 Apr 2026 17:15:38 +0800 Subject: [PATCH 6/9] modify --- heu/library/algorithms/ashe/README.md | 31 ++++ heu/library/algorithms/ashe/ashe_tests.cc | 38 +++-- heu/library/algorithms/ashe/decryptor.cc | 6 +- heu/library/algorithms/ashe/decryptor.h | 11 +- heu/library/algorithms/ashe/encryptor.cc | 2 +- heu/library/algorithms/ashe/encryptor.h | 11 +- heu/library/algorithms/ashe/evaluator.cc | 29 ++-- heu/library/algorithms/ashe/evaluator.h | 11 +- heu/library/algorithms/ashe/key_generator.cc | 47 ++++-- heu/library/algorithms/ashe/key_generator.h | 4 +- .../algorithms/ashe/public_parameters.cc | 12 +- .../algorithms/ashe/public_parameters.h | 25 ++- heu/library/numpy/numpy.h | 6 +- heu/library/phe/base/schema.cc | 4 +- heu/library/phe/base/schema.h | 5 +- heu/library/phe/phe.cc | 153 ++++++++++++++---- heu/library/phe/phe.h | 2 + 17 files changed, 276 insertions(+), 121 deletions(-) create mode 100644 heu/library/algorithms/ashe/README.md diff --git a/heu/library/algorithms/ashe/README.md b/heu/library/algorithms/ashe/README.md new file mode 100644 index 0000000..3a43b2c --- /dev/null +++ b/heu/library/algorithms/ashe/README.md @@ -0,0 +1,31 @@ +Implementation of a Variant of Improved Symmetric Homomorphic Encryption(iSHE) + +KeyGen(key_size): + +- Sample a $k_p$-bit (usually $k_p=1536$) prime $p$ +- Sample a $k_q$-bit (usually $k_q=512$) primes $q$ +- Set $k_{r1}, k_{r2}$, the length of random numbers +- Set the message space parameter $k_m=64$ +- The private key is $(p, q)$ and the public parameter is all the parameters $(k_p, k_q, k_{r1}, k_{r2}, k_m)$ and pre-computed ciphertext of $0$ + +Encryption(sk, pp, m): + +- Sample $r_1 \gets \{0,1\}^{k_{r1}}, r_2 \gets \{0,1\}^{k_{r2}}$ +- The ciphertext is $c = r_1 \cdot p + r_2 \cdot q + (m\ \text{mod}\ (2^{k_m-1}-1))$ + +Decryption(sk, c): + +- Compute $m' = c\ (\text{mod}\ p\ (\text{mod}\ q\ (\ \text{mod}\ (2^{k_m-1}-1)))$ +- If $m' \le 2^{k_m-1}-1$ return m' else return $m'- 2^{k_m-1}-1$ + +Additive homomorphisms: + +- Add $(c_1, c_2) = c_1 + c_2$ +- AddPlain $(c, m) = c + (m\ (\ \text{mod}\ 2^{k_m-1}-1))$ +- Negate $\text{MulPlain}(a, 2^{k_m-1}-2)$ + +Multiplicative homomorphism: + +- MulPlain $(c, m) = c \cdot m$ + +This implement focus on 2048bits key size and 112bit security. The argument keysize in key_generator is actually the scale of dataset. \ No newline at end of file diff --git a/heu/library/algorithms/ashe/ashe_tests.cc b/heu/library/algorithms/ashe/ashe_tests.cc index 5036569..ef2cb0d 100644 --- a/heu/library/algorithms/ashe/ashe_tests.cc +++ b/heu/library/algorithms/ashe/ashe_tests.cc @@ -22,18 +22,18 @@ namespace heu::lib::algorithms::ashe::test { class asheTest : public testing::Test { protected: - static void SetUpTestSuite() { KeyGenerator::Generate(4096, &sk_, &pp_); } + static void SetUpTestSuite() { KeyGenerator::Generate(2048, &sk_, &pp_); } static SecretKey sk_; - static PublicParameters pp_; + static PublicKey pp_; }; SecretKey asheTest::sk_; -PublicParameters asheTest::pp_; +PublicKey asheTest::pp_; TEST_F(asheTest, SerializeTest) { auto pp_buffer = pp_.Serialize(); - PublicParameters pp2; + PublicKey pp2; pp2.Deserialize(pp_buffer); ASSERT_EQ(pp_.k_r1, pp2.k_r1); ASSERT_EQ(pp_.k_r2, pp2.k_r2); @@ -139,7 +139,16 @@ TEST_F(asheTest, NegateEvalutate) { Encryptor encryptor_(pp_, sk_); Evaluator evaluator_(pp_); Decryptor decryptor_(pp_, sk_); - Plaintext p = Plaintext(123456); + Plaintext p1 = Plaintext(123456); + Plaintext p2 = Plaintext(23456); + Ciphertext c1 = encryptor_.Encrypt(p1); + Ciphertext c2 = encryptor_.Encrypt(p2); + Ciphertext c3 = evaluator_.Sub(c1, c2); + decryptor_.Decrypt(c3, &p1); + EXPECT_EQ(BigInt(123456 - 23456), p1); + evaluator_.NegateInplace(&c2); + decryptor_.Decrypt(c2, &p2); + EXPECT_EQ(BigInt(-23456), p2); } TEST_F(asheTest, RuntimeEfficientTest) { @@ -148,21 +157,22 @@ TEST_F(asheTest, RuntimeEfficientTest) { Decryptor decryptor_(pp_, sk_); Ciphertext c1, c2; std::chrono::time_point t1, t2; + c1 = encryptor_.Encrypt(pp_.MessageSpace().second); + c2 = encryptor_.Encrypt(pp_.MessageSpace().second); t1 = std::chrono::high_resolution_clock::now(); - for (int i = 0; i < 10000; i++) { - c1 = encryptor_.Encrypt(BigInt(123456)); + for (int i = 0; i < 100000; i++) { + evaluator_.AddInplace(&c1, c2); + // Plaintext m = decryptor_.Decrypt(c2); + // std::cout << m << std::endl; + // EXPECT_EQ(m, BigInt(-1)*BigInt(i + 2)); } t2 = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(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(t2 - t1); std::cout << "add 1w times used " << duration.count() << std::endl; + auto p = decryptor_.Decrypt(c1); + std::cout << p << std::endl; + EXPECT_EQ(p, pp_.MessageSpace().second * 100001); t1 = std::chrono::high_resolution_clock::now(); for (int i = 0; i < 10000; i++) { Plaintext m = decryptor_.Decrypt(c2); diff --git a/heu/library/algorithms/ashe/decryptor.cc b/heu/library/algorithms/ashe/decryptor.cc index 4f17a64..0b65e4c 100644 --- a/heu/library/algorithms/ashe/decryptor.cc +++ b/heu/library/algorithms/ashe/decryptor.cc @@ -20,7 +20,9 @@ void Decryptor::Decrypt(const Ciphertext &ct, Plaintext *out) const { } 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; + BigInt m = ct.n_ % p % q; + m = m % MOD_; + if (m >= half) m = m - MOD_; + return m; } } // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/decryptor.h b/heu/library/algorithms/ashe/decryptor.h index b3ae071..4329504 100644 --- a/heu/library/algorithms/ashe/decryptor.h +++ b/heu/library/algorithms/ashe/decryptor.h @@ -23,10 +23,12 @@ namespace heu::lib::algorithms::ashe { class Decryptor { public: - explicit Decryptor(PublicParameters pp, SecretKey sk) + explicit Decryptor(PublicKey pp, SecretKey sk) : pp_(std::move(pp)), sk_(std::move(sk)) { p = sk_.p_; q = sk_.q_; + MOD_ = BigInt(1) << 192; + half = BigInt(1) << 191; } void Decrypt(const Ciphertext &ct, Plaintext *out) const; @@ -34,12 +36,11 @@ class Decryptor { [[nodiscard]] Plaintext Decrypt(const Ciphertext &ct) const; private: - PublicParameters pp_; + PublicKey pp_; SecretKey sk_; - BigInt half = BigInt(UINT64_MAX) / BigInt(2); - BigInt MAX = BigInt(UINT64_MAX); + BigInt half; + BigInt MOD_; BigInt p; BigInt q; - BigInt ZERO = BigInt(0); }; } // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/encryptor.cc b/heu/library/algorithms/ashe/encryptor.cc index 4dadc12..2977a3c 100644 --- a/heu/library/algorithms/ashe/encryptor.cc +++ b/heu/library/algorithms/ashe/encryptor.cc @@ -42,7 +42,7 @@ Ciphertext Encryptor::EncryptImpl(const Plaintext &m, BigInt r, r1; BigInt::RandomExactBits(pp_.k_r1, &r); BigInt::RandomExactBits(pp_.k_r2, &r1); - const BigInt m1 = r * sk_.p_ + r1 * sk_.q_ + m.AddMod(ZERO, MAX); + const BigInt m1 = r * sk_.p_ + r1 * sk_.q_ + m % MOD_; if constexpr (audit) { YACL_ENFORCE(audit_str != nullptr); diff --git a/heu/library/algorithms/ashe/encryptor.h b/heu/library/algorithms/ashe/encryptor.h index d5bf2c4..fee2915 100644 --- a/heu/library/algorithms/ashe/encryptor.h +++ b/heu/library/algorithms/ashe/encryptor.h @@ -23,8 +23,10 @@ namespace heu::lib::algorithms::ashe { class Encryptor { public: - explicit Encryptor(PublicParameters pk, SecretKey sk) - : pp_(std::move(pk)), sk_(std::move(sk)) {} + explicit Encryptor(PublicKey pk, SecretKey sk) + : pp_(std::move(pk)), sk_(std::move(sk)) { + MOD_ = BigInt(1) << 192; + } [[nodiscard]] Ciphertext EncryptZero() const; [[nodiscard]] Ciphertext Encrypt(const Plaintext &m) const; @@ -37,9 +39,8 @@ class Encryptor { private: template Ciphertext EncryptImpl(const Plaintext &m, std::string *audit_str) const; - PublicParameters pp_; + PublicKey pp_; SecretKey sk_; - BigInt ZERO = BigInt(0); - BigInt MAX = BigInt(UINT64_MAX); + BigInt MOD_; }; } // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/evaluator.cc b/heu/library/algorithms/ashe/evaluator.cc index 38c4712..9cf205a 100644 --- a/heu/library/algorithms/ashe/evaluator.cc +++ b/heu/library/algorithms/ashe/evaluator.cc @@ -14,8 +14,6 @@ #include "heu/library/algorithms/ashe/evaluator.h" -#include "fmt/ranges.h" - namespace heu::lib::algorithms::ashe { void Evaluator::Randomize(Ciphertext *ct) const { BigInt r; @@ -28,7 +26,7 @@ Ciphertext Evaluator::Add(const Ciphertext &a, const Ciphertext &b) const { } Ciphertext Evaluator::Add(const Ciphertext &a, const Plaintext &b) const { - return Ciphertext(a.n_ + b % MAX); + return Ciphertext(a.n_ + b % MOD_); } Ciphertext Evaluator::Add(const Plaintext &a, const Ciphertext &b) const { @@ -40,11 +38,15 @@ Plaintext Evaluator::Add(const Plaintext &a, const Plaintext &b) const { } void Evaluator::AddInplace(Ciphertext *a, const Ciphertext &b) const { - *a = Add(*a, b); + a->n_ += b.n_; } void Evaluator::AddInplace(Ciphertext *a, const Plaintext &b) const { - *a = Add(*a, b); + if (b.IsNegative()) { + a->n_ += b + MOD_; + } else { + a->n_ += b; + } } void Evaluator::AddInplace(Plaintext *a, const Plaintext &b) const { @@ -52,8 +54,7 @@ void Evaluator::AddInplace(Plaintext *a, const Plaintext &b) const { } Ciphertext Evaluator::Sub(const Ciphertext &a, const Ciphertext &b) const { - const Ciphertext b_ = Negate(b); - return Add(a, b_); + return Ciphertext(a.n_ - b.n_); } Ciphertext Evaluator::Sub(const Ciphertext &a, const Plaintext &b) const { @@ -81,11 +82,12 @@ void Evaluator::SubInplace(Plaintext *a, const Plaintext &b) const { } Ciphertext Evaluator::Mul(const Ciphertext &a, const Plaintext &b) const { - YACL_ENFORCE(b % MAX <= BigInt(2).Pow(16), - "Plaintext {} is too large, cannot encrypt.", b); - Ciphertext res; - res.n_ = b.AddMod(ZERO, MAX) * a.n_; - return res; + if (!b.IsNegative()) { + return Ciphertext(b * a.n_); + } else { + Ciphertext neg_a = Negate(a); + return Ciphertext((-b) * neg_a.n_); + } } Ciphertext Evaluator::Mul(const Plaintext &a, const Ciphertext &b) const { @@ -105,8 +107,7 @@ void Evaluator::MulInplace(Plaintext *a, const Plaintext &b) const { } Ciphertext Evaluator::Negate(const Ciphertext &a) const { - const BigInt neg = BigInt(-1) % MAX; - return Mul(a, neg); + return Ciphertext(MOD_ - a.n_); } void Evaluator::NegateInplace(Ciphertext *a) const { *a = Negate(*a); } diff --git a/heu/library/algorithms/ashe/evaluator.h b/heu/library/algorithms/ashe/evaluator.h index 8e85b5b..4cb2382 100644 --- a/heu/library/algorithms/ashe/evaluator.h +++ b/heu/library/algorithms/ashe/evaluator.h @@ -22,7 +22,9 @@ namespace heu::lib::algorithms::ashe { class Evaluator { public: - explicit Evaluator(PublicParameters pp) : pp_(std::move(pp)) {} + explicit Evaluator(PublicKey pp) : pp_(std::move(pp)) { + MOD_ = BigInt(1) << 192; + } void Randomize(Ciphertext *ct) const; @@ -55,10 +57,7 @@ class Evaluator { void NegateInplace(Ciphertext *a) const; private: - PublicParameters pp_; - BigInt ONE = BigInt(1); - BigInt ZERO = BigInt(0); - BigInt MAX = BigInt(UINT64_MAX); - BigInt PlainSpace = BigInt(2).Pow(16); + PublicKey pp_; + BigInt MOD_; }; } // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/key_generator.cc b/heu/library/algorithms/ashe/key_generator.cc index 9509494..81dd124 100644 --- a/heu/library/algorithms/ashe/key_generator.cc +++ b/heu/library/algorithms/ashe/key_generator.cc @@ -17,21 +17,36 @@ #include namespace heu::lib::algorithms::ashe { -void KeyGenerator::Generate(int key_size, SecretKey *sk, PublicParameters *pk) { +void KeyGenerator::Generate(int key_size, SecretKey *sk, PublicKey *pk) { int64_t k_r1, k_p, k_q, k_r2, k_m; - ; if (key_size == 2048) { - k_r1 = 4384; - k_p = 1536; - k_q = 1008; - k_r2 = 512; - k_m = 64; + // < 10w + k_r1 = 3978; + k_p = 777; + k_q = 256; + k_r2 = 504; + k_m = 128; + } else if (key_size == 219) { + // < 50w + k_r1 = 5160; + k_p = 779; + k_q = 256; + k_r2 = 504; + k_m = 128; + } else if (key_size == 220) { + // < 100w + k_r1 = 5800; + k_p = 780; + k_q = 256; + k_r2 = 504; + k_m = 128; } else { - k_r1 = 8832; - k_p = 1536; - k_q = 992; - k_r2 = 512; - k_m = 64; + // <300w + k_r1 = 7180; + k_p = 782; + k_q = 256; + k_r2 = 504; + k_m = 128; } std::vector zeros; BigInt p = BigInt::RandPrimeOver(k_p); @@ -39,19 +54,19 @@ void KeyGenerator::Generate(int key_size, SecretKey *sk, PublicParameters *pk) { *sk = SecretKey(p, q); InitZeros(k_r1, k_p, k_q, k_r2, k_m, *sk, &zeros); - *pk = PublicParameters(k_r1, k_p, k_q, k_r2, k_m, zeros); + *pk = PublicKey(k_r1, k_p, k_q, k_r2, k_m, zeros); } -void KeyGenerator::Generate(SecretKey *sk, PublicParameters *pk) { +void KeyGenerator::Generate(SecretKey *sk, PublicKey *pk) { Generate(2048, sk, pk); } void KeyGenerator::InitZeros(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, int64_t k_m, SecretKey sk_, std::vector *zeros) { - auto tmp = PublicParameters(k_r1, k_p, k_q, k_r2, k_m); + auto tmp = PublicKey(k_r1, k_p, k_q, k_r2, k_m); auto et = Encryptor(tmp, std::move(sk_)); - for (int i = 1; i <= 20; ++i) { + for (int i = 1; i <= 100; ++i) { zeros->emplace_back(et.Encrypt(BigInt(0)).n_); } } diff --git a/heu/library/algorithms/ashe/key_generator.h b/heu/library/algorithms/ashe/key_generator.h index 4646fdf..9081b35 100644 --- a/heu/library/algorithms/ashe/key_generator.h +++ b/heu/library/algorithms/ashe/key_generator.h @@ -21,8 +21,8 @@ namespace heu::lib::algorithms::ashe { class KeyGenerator { public: - static void Generate(int key_size, SecretKey *sk, PublicParameters *pk); - static void Generate(SecretKey *sk, PublicParameters *pk); + static void Generate(int key_size, SecretKey *sk, PublicKey *pk); + static void Generate(SecretKey *sk, PublicKey *pk); private: static void InitZeros(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, diff --git a/heu/library/algorithms/ashe/public_parameters.cc b/heu/library/algorithms/ashe/public_parameters.cc index 0610562..b12de39 100644 --- a/heu/library/algorithms/ashe/public_parameters.cc +++ b/heu/library/algorithms/ashe/public_parameters.cc @@ -15,7 +15,7 @@ #include "heu/library/algorithms/ashe/public_parameters.h" namespace heu::lib::algorithms::ashe { -PublicParameters::PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, +PublicKey::PublicKey(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, int64_t k_m) { this->k_r1 = k_r1; this->k_p = k_p; @@ -25,14 +25,14 @@ PublicParameters::PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, Init(); } -PublicParameters::PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, +PublicKey::PublicKey(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, int64_t k_m, const std::vector &zeros) - : PublicParameters(k_r1, k_p, k_q, k_r2, k_m) { + : PublicKey(k_r1, k_p, k_q, k_r2, k_m) { this->randomZeros = zeros; } -std::string PublicParameters::ToString() const { +std::string PublicKey::ToString() const { return fmt::format( "ashe PP: k_r1={}, k_p={}, k_q={}, " "k_r2={}, k_m={}, randomZeros={}[size:{}]", @@ -41,8 +41,8 @@ std::string PublicParameters::ToString() const { randomZeros.size()); } -void PublicParameters::Init() { +void PublicKey::Init() { this->M[1] = BigInt(2).Pow(k_m - 1) - BigInt(1); - this->M[0] = -this->M[1]; + this->M[0] = -BigInt(2).Pow(k_m - 1); } } // namespace heu::lib::algorithms::ashe diff --git a/heu/library/algorithms/ashe/public_parameters.h b/heu/library/algorithms/ashe/public_parameters.h index b5cc12e..a0a37bf 100644 --- a/heu/library/algorithms/ashe/public_parameters.h +++ b/heu/library/algorithms/ashe/public_parameters.h @@ -20,7 +20,7 @@ #include "heu/library/algorithms/util/he_object.h" namespace heu::lib::algorithms::ashe { -class PublicParameters : public HeObject { +class PublicKey : public HeObject { private: BigInt plaintextBound; @@ -38,28 +38,27 @@ class PublicParameters : public HeObject { } public: - int64_t k_r1 = 4384; - int64_t k_p = 1536; - int64_t k_q = 1008; - int64_t k_r2 = 512; - int64_t k_m = 64; + int64_t k_r1 = 2196; + int64_t k_p = 768; + int64_t k_q = 256; + int64_t k_r2 = 504; + int64_t k_m = 128; std::vector randomZeros; BigInt M[2]; - PublicParameters() = default; + PublicKey() = default; - PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, - int64_t k_m); + PublicKey(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, int64_t k_m); - PublicParameters(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, - int64_t k_m, const std::vector &zeros); + PublicKey(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, int64_t k_m, + const std::vector &zeros); - bool operator==(const PublicParameters &other) const { + bool operator==(const PublicKey &other) const { return k_r1 == other.k_r1 && k_p == other.k_p && k_q == other.k_q && k_r2 == other.k_r2 && k_m == other.k_m; } - bool operator!=(const PublicParameters &other) const { + bool operator!=(const PublicKey &other) const { return !this->operator==(other); } diff --git a/heu/library/numpy/numpy.h b/heu/library/numpy/numpy.h index c3cdcae..d6e112c 100644 --- a/heu/library/numpy/numpy.h +++ b/heu/library/numpy/numpy.h @@ -57,8 +57,10 @@ class DestinationHeKit : public phe::HeKitPublicBase { public: explicit DestinationHeKit(phe::DestinationHeKit phe_kit) { Setup(phe_kit.GetPublicKey()); - - encryptor_ = std::make_shared(*phe_kit.GetEncryptor()); + auto phe_encryptor = phe_kit.GetEncryptor(); + if (phe_encryptor != nullptr) { + encryptor_ = std::make_shared(*phe_encryptor); + } evaluator_ = std::make_shared(*phe_kit.GetEvaluator()); } diff --git a/heu/library/phe/base/schema.cc b/heu/library/phe/base/schema.cc index fbf8338..72010c5 100644 --- a/heu/library/phe/base/schema.cc +++ b/heu/library/phe/base/schema.cc @@ -25,8 +25,7 @@ namespace heu::lib::phe { SchemaType::enum_item, { #enum_item, ##__VA_ARGS__ } \ } #define MAP_ITEM_false(...) \ - { \ - } + {} #define MAP_ITEM_HELPER(enable, enum_item, ...) \ MAP_ITEM_##enable(enum_item, ##__VA_ARGS__) #define MAP_ITEM(enable, enum_item, ...) \ @@ -60,6 +59,7 @@ static const std::map, MAP_ITEM(true, DGK, "dgk", "damgard-geisler-kroigaard", "damgard_geisler_kroigaard"), MAP_ITEM(true, DJ, "dj", "damgard-jurik", "damgard_jurik"), + MAP_ITEM(true, AShe, "ashe", "aShe", "aSHE", "ASHE"), // MAP_ITEM(ENABLE, YOUR_ALGO, "one_or_more_name_alias"), }; diff --git a/heu/library/phe/base/schema.h b/heu/library/phe/base/schema.h index 4be56d0..1b1d5d6 100644 --- a/heu/library/phe/base/schema.h +++ b/heu/library/phe/base/schema.h @@ -16,6 +16,7 @@ #include "msgpack.hpp" +#include "heu/library/algorithms/ashe/ashe.h" #include "heu/library/algorithms/dgk/dgk.h" #include "heu/library/algorithms/dj/dj.h" #include "heu/library/algorithms/elgamal/elgamal.h" @@ -54,6 +55,7 @@ enum class SchemaType : uint8_t { ENUM_ELEMENT(8, true, ElGamal) ENUM_ELEMENT(10, true, DGK) ENUM_ELEMENT(11, true, DJ) + ENUM_ELEMENT(12, true, AShe) // YOUR_ALGO }; // clang-format on @@ -84,7 +86,8 @@ enum class SchemaType : uint8_t { INVOKE(ENABLE_CLUSTAR_FPGA, func_or_macro, ::heu::lib::algorithms::paillier_clustar_fpga, ##__VA_ARGS__) \ INVOKE(true, func_or_macro, ::heu::lib::algorithms::elgamal, ##__VA_ARGS__) \ INVOKE(true, func_or_macro, ::heu::lib::algorithms::dgk, ##__VA_ARGS__) \ - INVOKE(true, func_or_macro, ::heu::lib::algorithms::dj, ##__VA_ARGS__) + INVOKE(true, func_or_macro, ::heu::lib::algorithms::dj, ##__VA_ARGS__) \ + INVOKE(true, func_or_macro, ::heu::lib::algorithms::ashe, ##__VA_ARGS__) // [SPI: Please register your algorithm here] || progress: (4 of 5) // If you add a new schema, change this !! diff --git a/heu/library/phe/phe.cc b/heu/library/phe/phe.cc index 3f4166d..b80755c 100644 --- a/heu/library/phe/phe.cc +++ b/heu/library/phe/phe.cc @@ -18,6 +18,55 @@ namespace heu::lib::phe { +template +struct CanConstructWithPkOnly : std::false_type {}; + +template +struct CanConstructWithPkOnly()))>> + : std::true_type {}; + +template ::value> +struct EncryptorCreator; + +template +struct EncryptorCreator { + static Enc create(const PK &pk, const SK &) { return Enc(pk); } +}; + +template +struct EncryptorCreator { + static Enc create(const PK &pk, const SK &sk) { return Enc(pk, sk); } +}; + +template ::value> +struct EncryptorSetupHelper; + +template +struct EncryptorSetupHelper { + static void setupWithPk(std::shared_ptr &encryptor, + SchemaType schema_type, const PK &pk) { + encryptor = std::make_shared(schema_type, Enc(pk)); + } + + static void setupWithSk(std::shared_ptr &, SchemaType, const PK &, + const SK &) {} +}; + +template +struct EncryptorSetupHelper { // symmetric + + static void setupWithPk(std::shared_ptr &, SchemaType, + const PK &) {} + + static void setupWithSk(std::shared_ptr &encryptor, + SchemaType schema_type, const PK &pk, const SK &sk) { + encryptor = std::make_shared(schema_type, Enc(pk, sk)); + } +}; + void HeKitPublicBase::Setup(std::shared_ptr pk) { public_key_ = std::move(pk); @@ -43,17 +92,41 @@ void HeKitSecretBase::Setup(std::shared_ptr pk, schema_type_); } -#define GEN_KEY_AND_INIT(ns) \ - [&](ns::PublicKey &pk) { \ - ns::SecretKey sk; \ - ns::KeyGenerator::Generate(key_size, &sk, &pk); \ - \ - encryptor_ = std::make_shared(schema_type, ns::Encryptor(pk)); \ - decryptor_ = \ - std::make_shared(schema_type, ns::Decryptor(pk, sk)); \ - evaluator_ = std::make_shared(schema_type, ns::Evaluator(pk)); \ - return std::make_shared(std::move(sk)); \ +#define GEN_KEY_AND_INIT(ns) \ + [&](ns::PublicKey &pk) { \ + ns::SecretKey sk; \ + ns::KeyGenerator::Generate(key_size, &sk, &pk); \ + \ + encryptor_ = std::make_shared( \ + schema_type, \ + EncryptorCreator::create( \ + pk, sk)); \ + decryptor_ = \ + std::make_shared(schema_type, ns::Decryptor(pk, sk)); \ + evaluator_ = std::make_shared(schema_type, ns::Evaluator(pk)); \ + return std::make_shared(std::move(sk)); \ + } + +template ::value> +struct DestEncryptorSetupHelper; + +template +struct DestEncryptorSetupHelper { + static void setup(std::shared_ptr &encryptor, + SchemaType schema_type, const PK &pk) { + encryptor = std::make_shared(schema_type, Enc(pk)); + } +}; + +template +struct DestEncryptorSetupHelper { + static void setup(std::shared_ptr &encryptor, + SchemaType schema_type, const PK &) { + (void)schema_type; + encryptor = nullptr; } +}; HeKit::HeKit(SchemaType schema_type, size_t key_size) { auto pk = std::make_shared(schema_type); @@ -62,16 +135,19 @@ HeKit::HeKit(SchemaType schema_type, size_t key_size) { Setup(std::move(pk), std::move(sk)); } -#define GEN_KEY_AND_INIT_DEFAULT(ns) \ - [&](ns::PublicKey &pk) { \ - ns::SecretKey sk; \ - ns::KeyGenerator::Generate(&sk, &pk); \ - \ - encryptor_ = std::make_shared(schema_type, ns::Encryptor(pk)); \ - decryptor_ = \ - std::make_shared(schema_type, ns::Decryptor(pk, sk)); \ - evaluator_ = std::make_shared(schema_type, ns::Evaluator(pk)); \ - return std::make_shared(std::move(sk)); \ +#define GEN_KEY_AND_INIT_DEFAULT(ns) \ + [&](ns::PublicKey &pk) { \ + ns::SecretKey sk; \ + ns::KeyGenerator::Generate(&sk, &pk); \ + \ + encryptor_ = std::make_shared( \ + schema_type, \ + EncryptorCreator::create( \ + pk, sk)); \ + decryptor_ = \ + std::make_shared(schema_type, ns::Decryptor(pk, sk)); \ + evaluator_ = std::make_shared(schema_type, ns::Evaluator(pk)); \ + return std::make_shared(std::move(sk)); \ } HeKit::HeKit(SchemaType schema_type) { @@ -81,18 +157,23 @@ HeKit::HeKit(SchemaType schema_type) { Setup(std::move(pk), std::move(sk)); } -#define HE_SPECIAL_SETUP_BY_PK(ns) \ - [&](const ns::PublicKey &pk1) { \ - evaluator_ = \ - std::make_shared(schema_type_, ns::Evaluator(pk1)); \ - encryptor_ = \ - std::make_shared(schema_type_, ns::Encryptor(pk1)); \ +#define HE_SPECIAL_SETUP_BY_PK(ns) \ + [&](const ns::PublicKey &pk1) { \ + evaluator_ = \ + std::make_shared(schema_type_, ns::Evaluator(pk1)); \ + EncryptorSetupHelper::setupWithPk(encryptor_, schema_type_, \ + pk1); \ } -#define HE_SPECIAL_SETUP_BY_SK(ns) \ - [&](const ns::SecretKey &sk1) { \ - decryptor_ = std::make_shared( \ - schema_type_, ns::Decryptor(public_key_->As(), sk1)); \ +#define HE_SPECIAL_SETUP_BY_SK(ns) \ + [&](const ns::SecretKey &sk1) { \ + const auto &pk1 = public_key_->As(); \ + decryptor_ = \ + std::make_shared(schema_type_, ns::Decryptor(pk1, sk1)); \ + EncryptorSetupHelper::setupWithSk(encryptor_, schema_type_, \ + pk1, sk1); \ } HeKit::HeKit(std::shared_ptr pk, std::shared_ptr sk) { @@ -113,16 +194,24 @@ HeKit::HeKit(yacl::ByteContainerView pk_buffer, secret_key_->Visit(HE_DISPATCH(HE_SPECIAL_SETUP_BY_SK)); } +#define HE_DEST_SETUP_BY_PK(ns) \ + [&](const ns::PublicKey &pk1) { \ + evaluator_ = \ + std::make_shared(schema_type_, ns::Evaluator(pk1)); \ + DestEncryptorSetupHelper::setup( \ + encryptor_, schema_type_, pk1); \ + } + DestinationHeKit::DestinationHeKit(std::shared_ptr pk) { Setup(std::move(pk)); - public_key_->Visit(HE_DISPATCH(HE_SPECIAL_SETUP_BY_PK)); + public_key_->Visit(HE_DISPATCH(HE_DEST_SETUP_BY_PK)); } DestinationHeKit::DestinationHeKit(yacl::ByteContainerView pk_buffer) { auto pk = std::make_shared(); pk->Deserialize(pk_buffer); Setup(std::move(pk)); - public_key_->Visit(HE_DISPATCH(HE_SPECIAL_SETUP_BY_PK)); + public_key_->Visit(HE_DISPATCH(HE_DEST_SETUP_BY_PK)); } } // namespace heu::lib::phe diff --git a/heu/library/phe/phe.h b/heu/library/phe/phe.h index 3b1ca70..2848950 100644 --- a/heu/library/phe/phe.h +++ b/heu/library/phe/phe.h @@ -94,6 +94,8 @@ class DestinationHeKit : public HeKitPublicBase { return encryptor_; } + [[nodiscard]] bool canEncrypt() const { return encryptor_ != nullptr; } + [[nodiscard]] const std::shared_ptr &GetEvaluator() const { return evaluator_; } From 51726a07cc988e497f81b4dbef95c1a9690f422a Mon Sep 17 00:00:00 2001 From: mqh <1767162258@qq.com> Date: Fri, 24 Apr 2026 17:29:39 +0800 Subject: [PATCH 7/9] modify --- heu/library/algorithms/ashe/README.md | 8 +++++--- heu/library/algorithms/ashe/ashe_tests.cc | 11 ++--------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/heu/library/algorithms/ashe/README.md b/heu/library/algorithms/ashe/README.md index 3a43b2c..00b4882 100644 --- a/heu/library/algorithms/ashe/README.md +++ b/heu/library/algorithms/ashe/README.md @@ -5,8 +5,9 @@ KeyGen(key_size): - Sample a $k_p$-bit (usually $k_p=1536$) prime $p$ - Sample a $k_q$-bit (usually $k_q=512$) primes $q$ - Set $k_{r1}, k_{r2}$, the length of random numbers -- Set the message space parameter $k_m=64$ -- The private key is $(p, q)$ and the public parameter is all the parameters $(k_p, k_q, k_{r1}, k_{r2}, k_m)$ and pre-computed ciphertext of $0$ +- Set the message space parameter $k_m=64$ +- The private key is $(p, q)$ and the public parameter is all the parameters $(k_p, k_q, k_{r1}, k_{r2}, k_m)$ and + pre-computed ciphertext of $0$ Encryption(sk, pp, m): @@ -28,4 +29,5 @@ Multiplicative homomorphism: - MulPlain $(c, m) = c \cdot m$ -This implement focus on 2048bits key size and 112bit security. The argument keysize in key_generator is actually the scale of dataset. \ No newline at end of file +This implement focus on 2048bits key size and 112bit security. The argument keysize in key_generator is actually the +scale of dataset. diff --git a/heu/library/algorithms/ashe/ashe_tests.cc b/heu/library/algorithms/ashe/ashe_tests.cc index ef2cb0d..aff2bea 100644 --- a/heu/library/algorithms/ashe/ashe_tests.cc +++ b/heu/library/algorithms/ashe/ashe_tests.cc @@ -19,9 +19,8 @@ #include "heu/library/algorithms/ashe/ashe.h" namespace heu::lib::algorithms::ashe::test { - class asheTest : public testing::Test { - protected: +protected: static void SetUpTestSuite() { KeyGenerator::Generate(2048, &sk_, &pp_); } static SecretKey sk_; @@ -143,12 +142,6 @@ TEST_F(asheTest, NegateEvalutate) { Plaintext p2 = Plaintext(23456); Ciphertext c1 = encryptor_.Encrypt(p1); Ciphertext c2 = encryptor_.Encrypt(p2); - Ciphertext c3 = evaluator_.Sub(c1, c2); - decryptor_.Decrypt(c3, &p1); - EXPECT_EQ(BigInt(123456 - 23456), p1); - evaluator_.NegateInplace(&c2); - decryptor_.Decrypt(c2, &p2); - EXPECT_EQ(BigInt(-23456), p2); } TEST_F(asheTest, RuntimeEfficientTest) { @@ -181,4 +174,4 @@ TEST_F(asheTest, RuntimeEfficientTest) { duration = std::chrono::duration_cast(t2 - t1); std::cout << "decrypt 1w times used " << duration.count() << std::endl; } -} // namespace heu::lib::algorithms::ashe::test +} // namespace heu::lib::algorithms::ashe::test From 520e6e455e6d45fe390dd4feddfc7eb0172ae7ae Mon Sep 17 00:00:00 2001 From: mqh <1767162258@qq.com> Date: Fri, 24 Apr 2026 18:13:08 +0800 Subject: [PATCH 8/9] modify --- heu/library/phe/base/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/heu/library/phe/base/BUILD.bazel b/heu/library/phe/base/BUILD.bazel index 12a5445..812d4ac 100644 --- a/heu/library/phe/base/BUILD.bazel +++ b/heu/library/phe/base/BUILD.bazel @@ -41,6 +41,7 @@ yacl_cc_library( "//heu/library/algorithms/paillier_ic", "//heu/library/algorithms/paillier_ipcl", "//heu/library/algorithms/paillier_zahlen", + "//heu/library/algorithms/ashe" ], ) From 949022ec955ec23871cad2a8a4ce112babf5a4fb Mon Sep 17 00:00:00 2001 From: mqh <1767162258@qq.com> Date: Fri, 24 Apr 2026 19:36:11 +0800 Subject: [PATCH 9/9] modify --- heu/library/algorithms/ashe/ashe_tests.cc | 11 +++++++++-- heu/library/algorithms/ashe/evaluator.cc | 5 ++++- heu/library/algorithms/ashe/key_generator.cc | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/heu/library/algorithms/ashe/ashe_tests.cc b/heu/library/algorithms/ashe/ashe_tests.cc index aff2bea..d21dd90 100644 --- a/heu/library/algorithms/ashe/ashe_tests.cc +++ b/heu/library/algorithms/ashe/ashe_tests.cc @@ -19,8 +19,9 @@ #include "heu/library/algorithms/ashe/ashe.h" namespace heu::lib::algorithms::ashe::test { + class asheTest : public testing::Test { -protected: + protected: static void SetUpTestSuite() { KeyGenerator::Generate(2048, &sk_, &pp_); } static SecretKey sk_; @@ -142,6 +143,12 @@ TEST_F(asheTest, NegateEvalutate) { Plaintext p2 = Plaintext(23456); Ciphertext c1 = encryptor_.Encrypt(p1); Ciphertext c2 = encryptor_.Encrypt(p2); + Ciphertext c3 = evaluator_.Sub(c1, c2); + c2 = evaluator_.Negate(c2); + decryptor_.Decrypt(c2, &p1); + EXPECT_EQ(p1, -23456); + decryptor_.Decrypt(c3, &p1); + EXPECT_EQ(BigInt(123456 - 23456), p1); } TEST_F(asheTest, RuntimeEfficientTest) { @@ -174,4 +181,4 @@ TEST_F(asheTest, RuntimeEfficientTest) { duration = std::chrono::duration_cast(t2 - t1); std::cout << "decrypt 1w times used " << duration.count() << std::endl; } -} // namespace heu::lib::algorithms::ashe::test +} // namespace heu::lib::algorithms::ashe::test diff --git a/heu/library/algorithms/ashe/evaluator.cc b/heu/library/algorithms/ashe/evaluator.cc index 9cf205a..ef945a0 100644 --- a/heu/library/algorithms/ashe/evaluator.cc +++ b/heu/library/algorithms/ashe/evaluator.cc @@ -107,7 +107,10 @@ void Evaluator::MulInplace(Plaintext *a, const Plaintext &b) const { } Ciphertext Evaluator::Negate(const Ciphertext &a) const { - return Ciphertext(MOD_ - a.n_); + BigInt r; + BigInt::RandomLtN(BigInt(pp_.randomZeros.size()), &r); + BigInt random0 = pp_.randomZeros[r.Get()]; + return Ciphertext(MOD_ - a.n_ + random0); } void Evaluator::NegateInplace(Ciphertext *a) const { *a = Negate(*a); } diff --git a/heu/library/algorithms/ashe/key_generator.cc b/heu/library/algorithms/ashe/key_generator.cc index 81dd124..2c306f3 100644 --- a/heu/library/algorithms/ashe/key_generator.cc +++ b/heu/library/algorithms/ashe/key_generator.cc @@ -64,7 +64,7 @@ void KeyGenerator::Generate(SecretKey *sk, PublicKey *pk) { void KeyGenerator::InitZeros(int64_t k_r1, int64_t k_p, int64_t k_q, int64_t k_r2, int64_t k_m, SecretKey sk_, std::vector *zeros) { - auto tmp = PublicKey(k_r1, k_p, k_q, k_r2, k_m); + auto tmp = PublicKey(k_r1 + 8, k_p, k_q, k_r2 + 8, k_m); auto et = Encryptor(tmp, std::move(sk_)); for (int i = 1; i <= 100; ++i) { zeros->emplace_back(et.Encrypt(BigInt(0)).n_);