diff --git a/heu/library/algorithms/ashe/BUILD.bazel b/heu/library/algorithms/ashe/BUILD.bazel new file mode 100644 index 0000000..43bd176 --- /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 = [ + ":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", + ], +) 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..5036569 --- /dev/null +++ b/heu/library/algorithms/ashe/ashe_tests.cc @@ -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 + +#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 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::ashe::test diff --git a/heu/library/algorithms/ashe/ciphertext.h b/heu/library/algorithms/ashe/ciphertext.h new file mode 100644 index 0000000..9668403 --- /dev/null +++ b/heu/library/algorithms/ashe/ciphertext.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/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..4f17a64 --- /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..b3ae071 --- /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..4dadc12 --- /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..d5bf2c4 --- /dev/null +++ b/heu/library/algorithms/ashe/encryptor.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 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..38c4712 --- /dev/null +++ b/heu/library/algorithms/ashe/evaluator.cc @@ -0,0 +1,113 @@ +// 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..8e85b5b --- /dev/null +++ b/heu/library/algorithms/ashe/evaluator.h @@ -0,0 +1,64 @@ +// 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..9509494 --- /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..4646fdf --- /dev/null +++ b/heu/library/algorithms/ashe/key_generator.h @@ -0,0 +1,31 @@ +// 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/encryptor.h" +#include "heu/library/algorithms/ashe/public_parameters.h" +#include "heu/library/algorithms/ashe/secret_key.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..0610562 --- /dev/null +++ b/heu/library/algorithms/ashe/public_parameters.cc @@ -0,0 +1,48 @@ +// 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 { +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..b5cc12e --- /dev/null +++ b/heu/library/algorithms/ashe/public_parameters.h @@ -0,0 +1,78 @@ +// 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..117fe5c --- /dev/null +++ b/heu/library/algorithms/ashe/secret_key.h @@ -0,0 +1,48 @@ +// 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