Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

add iSHE algorithm to HEU #148

Merged
merged 31 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4f2ad0e
add algorithm(ishe) which is an improved symmetric homomorphic encryp…
Alec-xdu Aug 1, 2024
4aa54df
1
Alec-xdu Aug 1, 2024
c338089
modify and add README.md
Alec-xdu Aug 2, 2024
fa5ae11
delete useless import
Alec-xdu Aug 2, 2024
e7d05d1
update class Itemtool's serialize/deserialize function
Alec-xdu Aug 5, 2024
c906b48
rewrite serialize part and fix some bugs in encryptor
Alec-xdu Aug 6, 2024
ab1be9d
Modified a function that was deleted by mistake
Alec-xdu Aug 7, 2024
38cd554
Merge remote-tracking branch 'upstream/main' into iSHE_add
Alec-xdu Aug 8, 2024
1eaed06
Modify
Alec-xdu Aug 8, 2024
6bef865
reformat
Alec-xdu Aug 8, 2024
a8b538e
modify
Alec-xdu Aug 10, 2024
0afc474
modify & rename
Alec-xdu Aug 12, 2024
69043bf
modify
Alec-xdu Aug 14, 2024
f12f1f3
modify
Alec-xdu Aug 19, 2024
875e0d2
modify
Alec-xdu Aug 25, 2024
2fe8d4c
update README.md
Alec-xdu Aug 28, 2024
c69be30
modify README.md
Alec-xdu Aug 29, 2024
1ef9969
add new line at eof on README.md
Alec-xdu Aug 29, 2024
ef8e546
reformat base.cc & base.h
Alec-xdu Aug 29, 2024
02dd9f2
Merge remote-tracking branch 'upstream/main' into iSHE_add
Alec-xdu Aug 29, 2024
7042b35
MODIFY
Alec-xdu Aug 29, 2024
35492d5
MODIFY
Alec-xdu Aug 29, 2024
ae7f296
MODIFY
Alec-xdu Aug 30, 2024
ca074dc
add test_file
Alec-xdu Aug 30, 2024
0c70119
modify
Alec-xdu Aug 30, 2024
f670487
reformat
Alec-xdu Aug 30, 2024
4281603
reformat
Alec-xdu Aug 30, 2024
5cd366f
Merge remote-tracking branch 'origin/iSHE_add' into iSHE_add
Alec-xdu Aug 30, 2024
b1bc291
modify
Alec-xdu Aug 30, 2024
3c6abba
modify
Alec-xdu Aug 30, 2024
beea1db
modify
Alec-xdu Aug 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions heu/algorithms/ishe/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# 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 = "ishe_tests",
)

yacl_cc_library(
name = "ishe",
hdrs = ["ishe.h"],
deps = [
"base",
"decryptor",
"encryptor",
"evaluator",
"he_kit",
],
)

yacl_cc_library(
name = "he_kit",
srcs = ["he_kit.cc"],
hdrs = ["he_kit.h"],
deps = [
":decryptor",
":encryptor",
":evaluator",
"//heu/spi/utils:formater",
"@yacl//yacl/utils:serializer",
],
alwayslink = 1,
)

yacl_cc_library(
name = "base",
srcs = ["base.cc"],
hdrs = ["base.h"],
deps = [
"//heu/spi/he/sketches/scalar/phe",
"//heu/spi/utils:formater",
"@com_github_msgpack_msgpack//:msgpack",
"@yacl//yacl/utils:serializer",
],
)

yacl_cc_library(
name = "encryptor",
srcs = ["encryptor.cc"],
hdrs = ["encryptor.h"],
deps = [
":base",
"//heu/spi/utils:formater",
],
)

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

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

yacl_cc_test(
name = "ishe_test",
srcs = ["//heu/algorithms/ishe:ishe_test.cc"],
Alec-xdu marked this conversation as resolved.
Show resolved Hide resolved
deps = [
":ishe",
],
)
65 changes: 65 additions & 0 deletions heu/algorithms/ishe/base.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

Alec-xdu marked this conversation as resolved.
Show resolved Hide resolved
// 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.

#include "heu/algorithms/ishe/base.h"

namespace heu::algos::ishe {

Plaintext ItemTool::Clone(const Plaintext &pt) const { return pt; }

Ciphertext ItemTool::Clone(const Ciphertext &ct) const {
return Ciphertext(ct.n_, ct.d_);
}

SecretKey::SecretKey(MPInt s, MPInt p, MPInt L) {
this->s_ = std::move(s);
this->p_ = std::move(p);
this->L_ = std::move(L);
}

PublicKey::PublicKey(const int k_0, const int k_r, MPInt M[2], MPInt N) {
this->k_0 = k_0;
this->k_r = k_r;
this->N = std::move(N);
this->M[0] = M[0];
this->M[1] = M[1];
}
Alec-xdu marked this conversation as resolved.
Show resolved Hide resolved

size_t ItemTool::Serialize(const Plaintext &pt, uint8_t *buf,
const size_t buf_len) const {
return pt.Serialize(buf, buf_len);
}

size_t ItemTool::Serialize(const Ciphertext &ct, uint8_t *buf,
const size_t buf_len) const {
const size_t n_len = Serialize(ct.n_, buf, buf_len);
if (n_len == 0 || n_len >= buf_len) {
// serialize failed or can not contain more bits
return 0; // return 0 as a symbol of failure
}
return n_len;
}

Plaintext ItemTool::DeserializePT(const yacl::ByteContainerView buffer) const {
Plaintext res;
res.Deserialize(buffer);
return res;
}

Ciphertext ItemTool::DeserializeCT(yacl::ByteContainerView buffer) const {
return Ciphertext(DeserializePT(buffer));
}

} // namespace heu::algos::ishe
105 changes: 105 additions & 0 deletions heu/algorithms/ishe/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2024 Ant Group Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <map>
#include <string>
#include <utility>

#include "yacl/base/byte_container_view.h"
#include "yacl/math/mpint/mp_int.h"

#include "heu/spi/he/sketches/common/keys.h"
#include "heu/spi/he/sketches/scalar/item_tool.h"

namespace heu::algos::ishe {

using yacl::math::MPInt;
using Plaintext = MPInt;

class Ciphertext {
public:
// default constructor
Ciphertext() = default;

explicit Ciphertext(const MPInt n) : n_(n) { d_ = MPInt(1); }

explicit Ciphertext(MPInt n, MPInt d) : n_(std::move(n)) {
this->d_ = std::move(d);
}

[[nodiscard]] std::string ToString() const { return n_.ToString(); }

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

MPInt n_, d_;
};

class SecretKey : public spi::EmptyKeySketch<spi::HeKeyType::SecretKey> {
usafchn marked this conversation as resolved.
Show resolved Hide resolved
private:
MPInt s_, p_, L_;

public:
SecretKey(MPInt s, MPInt p, MPInt L);
SecretKey() = default;

MPInt getS() { return this->s_; }
usafchn marked this conversation as resolved.
Show resolved Hide resolved

MPInt getP() { return this->p_; }

MPInt getL() { return this->L_; }
};

class PublicKey : public spi::EmptyKeySketch<spi::HeKeyType::PublicKey> {
Alec-xdu marked this conversation as resolved.
Show resolved Hide resolved
private:
MPInt N, M[2];

public:
int k_r = 80;
int k_0 = 1024;
PublicKey() = default;
explicit PublicKey(int k_0, int k_r, MPInt M[2], MPInt N);

[[nodiscard]] size_t Keysize() const { return 2 * k_0; }

[[nodiscard]] MPInt *messageSpace() { return M; }
usafchn marked this conversation as resolved.
Show resolved Hide resolved

[[nodiscard]] std::map<std::string, std::string> ListParams() const override {
return {{"key_size", fmt::to_string(k_0)},
{"random_number_size", fmt::to_string(k_r)},
{"message_space_size", fmt::to_string(M[1])}};
}

[[nodiscard]] MPInt getN() const { return N; }
};

class ItemTool : public spi::ItemToolScalarSketch<Plaintext, Ciphertext,
SecretKey, PublicKey> {
public:
[[nodiscard]] Plaintext Clone(const Plaintext &pt) const override;
[[nodiscard]] Ciphertext Clone(const Ciphertext &ct) const override;

size_t Serialize(const Plaintext &pt, uint8_t *buf,
size_t buf_len) const override;
size_t Serialize(const Ciphertext &ct, uint8_t *buf,
size_t buf_len) const override;

[[nodiscard]] Plaintext DeserializePT(
yacl::ByteContainerView buffer) const override;
[[nodiscard]] Ciphertext DeserializeCT(
yacl::ByteContainerView buffer) const override;
};

} // namespace heu::algos::ishe
41 changes: 41 additions & 0 deletions heu/algorithms/ishe/decryptor.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// 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.

#include "heu/algorithms/ishe/decryptor.h"

namespace heu::algos::ishe {

void Decryptor::Decrypt(const Ciphertext &ct, Plaintext *out) const {
*out = Decrypt(ct);
}

Plaintext Decryptor::Decrypt(const Ciphertext &ct) const {
/**
* decrypt
* m: plaintext
* d: s's exponent
*/
MPInt tmp;
MPInt::PowMod(sk_->getS(), ct.d_, pk_->getN(), &tmp); // m = s^d
MPInt::InvertMod(tmp, pk_->getN(), &tmp); // (s^d)^-1
MPInt::MulMod(ct.n_, tmp, pk_->getN(), &tmp); // (s^d)^-1 * m mod N
MPInt::Mod(tmp, sk_->getP(), &tmp);
MPInt::Mod(tmp, sk_->getL(), &tmp); // (((s^d)^-1 * m mod N ) mod p) mod L
if (tmp < sk_->getL() / MPInt(2)) { // case 1 : m' < L/2
return tmp;
}
return tmp - sk_->getL(); // case 2 : else
}

} // namespace heu::algos::ishe
35 changes: 35 additions & 0 deletions heu/algorithms/ishe/decryptor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2024 Ant Group Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <utility>

#include "heu/algorithms/ishe/base.h"
#include "heu/spi/he/sketches/scalar/decryptor.h"

namespace heu::algos::ishe {

class Decryptor : public spi::DecryptorScalarSketch<Plaintext, Ciphertext> {
public:
std::shared_ptr<SecretKey> sk_;
std::shared_ptr<PublicKey> pk_;
usafchn marked this conversation as resolved.
Show resolved Hide resolved
void Decrypt(const Ciphertext &ct, Plaintext *out) const override;
[[nodiscard]] Plaintext Decrypt(const Ciphertext &ct) const override;

Decryptor(std::shared_ptr<SecretKey> sk, std::shared_ptr<PublicKey> pk)
: sk_(std::move(sk)), pk_(std::move(pk)) {}
};

} // namespace heu::algos::ishe
52 changes: 52 additions & 0 deletions heu/algorithms/ishe/encryptor.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// 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.

#include "heu/algorithms/ishe/encryptor.h"

#include <string>

namespace heu::algos::ishe {

Ciphertext Encryptor::EncryptZeroT() const {
return Ciphertext({0_mp}, {1_mp});
}

Ciphertext Encryptor::Encrypt(const Plaintext &m, const MPInt &d) const {
YACL_ENFORCE(m < pk_->messageSpace()[1] && m >= pk_->messageSpace()[0],
"Plaintext {} is too large, cannot encrypt.", m.ToString());
MPInt r, r1;
MPInt::RandomExactBits(pk_->k_r, &r); // r = {0,1}^k_r
MPInt::RandomExactBits(pk_->k_0, &r1); // r' ={0,1}^k_0
MPInt m1 = sk_->getS().PowMod(d, pk_->getN()); // m' = s^d
m1 *= (r * sk_->getL() + m); // m' = s*(rL+m)
m1 = m1.MulMod((MPInt(1) + r1 * sk_->getP()), pk_->getN());
// m' = s*(rL+m)*(1+r'p) mod N
return Ciphertext(m1, MPInt(1));
}

Ciphertext Encryptor::Encrypt(const Plaintext &m) const {
return Encrypt(m, MPInt(1));
}

void Encryptor::Encrypt(const Plaintext &m, Ciphertext *out) const {
*out = Encrypt(m);
}

void Encryptor::EncryptWithAudit(const Plaintext &m, Ciphertext *ct_out,
std::string *audit_out) const {
Encrypt(m, ct_out);
audit_out->assign(fmt::format("ishe:{}", ct_out->n_.ToString()));
}

} // namespace heu::algos::ishe
Loading
Loading