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

【OSCP】 + 在 YACL 上实现对称可搜索加密算法 #423

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions yacl/examples/sse/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,6 @@ yacl_cc_test(
],
deps = [
":sse",
"//yacl/crypto/rand",
],
)
41 changes: 23 additions & 18 deletions yacl/examples/sse/sse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ Sse::Sse(int bucket_size, int slot_size, int lambda, int n_lambda)
std::string Sse::GetKt() { return k_map_["Kt"]; }

// EDBSetup
std::pair<std::vector<std::vector<TSet::Record>>, std::string> Sse::EDBSetup() {
ProcessAndUpdateTAndXSet();
std::pair<std::vector<std::vector<TSet::Record>>, std::string> Sse::EDBSetup(
const uint128_t& iv) {
ProcessAndUpdateTAndXSet(iv);
auto [TSet, Kt] = tset_.TSetSetup(T_, keywords_);
TSet_ = TSet;
k_map_["Kt"] = Kt;
Expand Down Expand Up @@ -58,7 +59,7 @@ Sse::LoadEDB(const std::string& k_map_file, const std::string& tset_file,

// SearchProtocol
std::vector<std::string> Sse::SearchProtocol(
const std::vector<std::string>& keywords_Search) {
const std::vector<std::string>& keywords_Search, const uint128_t& iv) {
if (keywords_Search.empty()) {
return {};
}
Expand All @@ -84,14 +85,14 @@ std::vector<std::string> Sse::SearchProtocol(
hmac_F_SSE_Search_Kz.Update(w1 + std::to_string(c));
auto mac_z1 = hmac_F_SSE_Search_Kz.CumulativeMac();
std::string string_z1 = VectorToString(mac_z1);
yacl::math::MPInt z1(string_z1);
yacl::math::MPInt z1(string_z1, 10);
z1 = z1.Mod(ec_group_->GetOrder());

hmac_F_SSE_Search_Kx.Reset();
hmac_F_SSE_Search_Kx.Update(keywords_Search[i - 1]);
auto mac_for_xtag_search = hmac_F_SSE_Search_Kx.CumulativeMac();
std::string string_for_xtag_search = VectorToString(mac_for_xtag_search);
yacl::math::MPInt for_xtag_search(string_for_xtag_search);
yacl::math::MPInt for_xtag_search(string_for_xtag_search, 10);
for_xtag_search = for_xtag_search.Mod(ec_group_->GetOrder());

auto for_ecc_search = for_xtag_search.MulMod(z1, ec_group_->GetOrder());
Expand All @@ -105,7 +106,7 @@ std::vector<std::string> Sse::SearchProtocol(
bool found = false;
for (size_t c = 1; c <= size; c++) {
auto [e, y_string] = t[c - 1];
yacl::math::MPInt y(y_string);
yacl::math::MPInt y(y_string, 10);

bool allInXSet = true;
for (size_t i = 2; i <= keywords_Search.size(); i++) {
Expand Down Expand Up @@ -134,7 +135,7 @@ std::vector<std::string> Sse::SearchProtocol(
auto Ke_mac = hmac_F_SSE_Search_Ks.CumulativeMac();
uint128_t Ke = ConvertToUint128(Ke_mac);
for (const auto& e : E) {
std::vector<uint8_t> ind = AesCtrDecrypt(e, Ke, 0);
std::vector<uint8_t> ind = AesCtrDecrypt(e, Ke, iv);
std::string ind_string(ind.begin(), ind.end());
std::cout << "Found match: " << ind_string << std::endl;
results.push_back(ind_string);
Expand Down Expand Up @@ -168,17 +169,21 @@ void Sse::Initialize() {
keyValuePairs_ = keyValuePairs;
reverseIndex_ = reverseIndex;

k_map_["Ks"] = "This is Ks";
k_map_["Kx"] = "This is Kx";
k_map_["Ki"] = "This is Ki";
k_map_["Kz"] = "This is Kz";
auto rand_bytes_Ks = yacl::crypto::RandU32();
auto rand_bytes_Kx = yacl::crypto::RandU32();
auto rand_bytes_Ki = yacl::crypto::RandU32();
auto rand_bytes_Kz = yacl::crypto::RandU32();
k_map_["Ks"] = std::to_string(rand_bytes_Ks);
k_map_["Kx"] = std::to_string(rand_bytes_Kx);
k_map_["Ki"] = std::to_string(rand_bytes_Ki);
k_map_["Kz"] = std::to_string(rand_bytes_Kz);

const auto& curve = yacl::crypto::GetCurveMetaByName("secp224r1");
ec_group_ = yacl::crypto::openssl::OpensslGroup::Create(curve);
}

// 主功能函数:计算并更新 T 和 XSet
void Sse::ProcessAndUpdateTAndXSet() {
void Sse::ProcessAndUpdateTAndXSet(const uint128_t& iv) {
yacl::crypto::HmacSha256 hmac_F_SSE_Ks(k_map_["Ks"]);
yacl::crypto::HmacSha256 hmac_F_SSE_Kx(k_map_["Kx"]);
yacl::crypto::HmacSha256 hmac_F_SSE_Ki(k_map_["Ki"]);
Expand All @@ -190,7 +195,7 @@ void Sse::ProcessAndUpdateTAndXSet() {

auto mac_for_xtag = hmac_F_SSE_Kx.Reset().Update(keyword).CumulativeMac();
std::string string_for_xtag = VectorToString(mac_for_xtag);
yacl::math::MPInt for_xtag(string_for_xtag);
yacl::math::MPInt for_xtag(string_for_xtag, 10);
for_xtag = for_xtag.Mod(ec_group_->GetOrder());

std::vector<std::string> inds = FetchKeysByValue(reverseIndex_, keyword);
Expand All @@ -200,15 +205,15 @@ void Sse::ProcessAndUpdateTAndXSet() {
// xind
auto mac_xind = hmac_F_SSE_Ki.Reset().Update(ind).CumulativeMac();
std::string string_xind = VectorToString(mac_xind);
yacl::math::MPInt xind(string_xind);
yacl::math::MPInt xind(string_xind, 10);
xind = xind.Mod(ec_group_->GetOrder());

// z
auto mac_z = hmac_F_SSE_Kz.Reset()
.Update(keyword + std::to_string(c))
.CumulativeMac();
std::string string_z = VectorToString(mac_z);
yacl::math::MPInt z(string_z);
yacl::math::MPInt z(string_z, 10);
z = z.Mod(ec_group_->GetOrder());

// Invert_z
Expand All @@ -218,7 +223,7 @@ void Sse::ProcessAndUpdateTAndXSet() {

// append (e, y) to t.
std::vector<uint8_t> ind_vector(ind.begin(), ind.end());
std::vector<uint8_t> e = AesCtrEncrypt(ind_vector, Ke, 0);
std::vector<uint8_t> e = AesCtrEncrypt(ind_vector, Ke, iv);
t.push_back(std::make_pair(e, y.ToString()));

// add xtag to XSet.
Expand Down Expand Up @@ -517,8 +522,8 @@ std::vector<yacl::crypto::EcPoint> Sse::LoadXSet(
xset_file.read(&y_str[0], y_size);

// 从字符串构造MPInt
yacl::math::MPInt x(x_str);
yacl::math::MPInt y(y_str);
yacl::math::MPInt x(x_str, 10);
yacl::math::MPInt y(y_str, 10);

yacl::crypto::AffinePoint affine_point{x, y};
XSet.push_back(ec_group->CopyPoint(affine_point));
Expand Down
7 changes: 4 additions & 3 deletions yacl/examples/sse/sse.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class Sse {
Sse(int bucket_size = 8, int slot_size = 8, int lambda = 128,
int n_lambda = 256);

std::pair<std::vector<std::vector<TSet::Record>>, std::string> EDBSetup();
std::pair<std::vector<std::vector<TSet::Record>>, std::string> EDBSetup(
xbw886 marked this conversation as resolved.
Show resolved Hide resolved
const uint128_t& iv);

std::string GetKt();
std::tuple<std::map<std::string, std::string>,
Expand All @@ -57,7 +58,7 @@ class Sse {
const std::string& xset_file = "/tmp/sse_test_data/XSet.bin");

std::vector<std::string> SearchProtocol(
xbw886 marked this conversation as resolved.
Show resolved Hide resolved
const std::vector<std::string>& keywords);
const std::vector<std::string>& keywords, const uint128_t& iv);

~Sse();

Expand All @@ -66,7 +67,7 @@ class Sse {
const yacl::crypto::EcPoint& xtag,
const std::vector<yacl::crypto::EcPoint>& XSet);
void Initialize();
void ProcessAndUpdateTAndXSet();
void ProcessAndUpdateTAndXSet(const uint128_t& iv);

std::tuple<std::vector<std::string>,
std::vector<std::pair<std::string, std::string>>,
Expand Down
25 changes: 14 additions & 11 deletions yacl/examples/sse/sse_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

#include <unordered_set>

#include "yacl/crypto/rand/rand.h"

namespace examples::sse {
auto iv = yacl::crypto::RandU32();

class SseTest : public ::testing::Test {
protected:
Expand All @@ -30,7 +33,7 @@ class SseTest : public ::testing::Test {
256); // n_lambda

// 设置EDB
auto [tset, kt] = sse_->EDBSetup();
auto [tset, kt] = sse_->EDBSetup(iv);
EXPECT_FALSE(tset.empty());
EXPECT_FALSE(kt.empty());
}
Expand All @@ -40,7 +43,7 @@ class SseTest : public ::testing::Test {

TEST_F(SseTest, BasicSearch) {
std::vector<std::string> keyword = {"race=Black"};
auto results = sse_->SearchProtocol(keyword);
auto results = sse_->SearchProtocol(keyword, iv);
std::unordered_set<std::string> expected_results = {"ID_130162", "ID_130165"};
EXPECT_EQ(results.size(), expected_results.size());
std::unordered_set<std::string> actual_results(results.begin(),
Expand All @@ -51,21 +54,21 @@ TEST_F(SseTest, BasicSearch) {
// 测试空关键词搜索
TEST_F(SseTest, EmptyKeywordSearch) {
std::vector<std::string> keyword_empty = {};
auto results = sse_->SearchProtocol(keyword_empty);
auto results = sse_->SearchProtocol(keyword_empty, iv);
EXPECT_TRUE(results.empty());
}

// 测试不存在的关键词搜索
TEST_F(SseTest, NonExistentKeywordSearch) {
std::vector<std::string> non_existent = {"education=NonExistent"};
auto results = sse_->SearchProtocol(non_existent);
auto results = sse_->SearchProtocol(non_existent, iv);
EXPECT_TRUE(results.empty());
}

// 测试两个关键词
TEST_F(SseTest, TwoKeywordsSearch) {
std::vector<std::string> two_keywords = {"race=Black", "gender=Male"};
auto results = sse_->SearchProtocol(two_keywords);
auto results = sse_->SearchProtocol(two_keywords, iv);
std::unordered_set<std::string> expected_results = {"ID_130162", "ID_130165"};
EXPECT_EQ(results.size(), expected_results.size());
std::unordered_set<std::string> actual_results(results.begin(),
Expand All @@ -77,7 +80,7 @@ TEST_F(SseTest, TwoKeywordsSearch) {
TEST_F(SseTest, ThreeKeywordsSearch) {
std::vector<std::string> three_keywords = {"race=Black", "gender=Male",
"relationship=Husband"};
auto results = sse_->SearchProtocol(three_keywords);
auto results = sse_->SearchProtocol(three_keywords, iv);
std::unordered_set<std::string> expected_results = {"ID_130165"};
EXPECT_EQ(results.size(), expected_results.size());
std::unordered_set<std::string> actual_results(results.begin(),
Expand All @@ -89,7 +92,7 @@ TEST_F(SseTest, ThreeKeywordsSearch) {
TEST_F(SseTest, TwoKeywordsNotExistSearch) {
std::vector<std::string> two_keywords_not_exist = {"race=Black",
"education=NonExistent"};
auto results = sse_->SearchProtocol(two_keywords_not_exist);
auto results = sse_->SearchProtocol(two_keywords_not_exist, iv);
EXPECT_TRUE(results.empty());
}

Expand All @@ -98,9 +101,9 @@ TEST_F(SseTest, SearchConsistency) {
std::vector<std::string> keyword = {"workclass=Private"};

// 第一次搜索
auto results1 = sse_->SearchProtocol(keyword);
auto results1 = sse_->SearchProtocol(keyword, iv);
// 第二次搜索
auto results2 = sse_->SearchProtocol(keyword);
auto results2 = sse_->SearchProtocol(keyword, iv);

// 验证两次搜索结果一致
EXPECT_EQ(results1.size(), results2.size());
Expand All @@ -113,7 +116,7 @@ TEST_F(SseTest, SearchConsistency) {
TEST_F(SseTest, SaveAndLoadEDB) {
// 首先执行一次搜索并保存结果
std::vector<std::string> keyword = {"education=Bachelors"};
auto results_before = sse_->SearchProtocol(keyword);
auto results_before = sse_->SearchProtocol(keyword, iv);

// 保存EDB到文件
std::string test_dir = "/tmp/sse_test_data/";
Expand All @@ -130,7 +133,7 @@ TEST_F(SseTest, SaveAndLoadEDB) {
test_dir + "K_map.bin", test_dir + "TSet.bin", test_dir + "XSet.bin");

// 使用加载后的实例执行相同的搜索
auto results_after = new_sse->SearchProtocol(keyword);
auto results_after = new_sse->SearchProtocol(keyword, iv);

// 验证搜索结果一致性
EXPECT_EQ(results_before.size(), results_after.size());
Expand Down
2 changes: 1 addition & 1 deletion yacl/examples/sse/tset.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ std::pair<std::vector<std::vector<TSet::Record>>, std::string> TSet::TSetSetup(
hmac_F_line_Tset.Update(keyword);
auto mac = hmac_F_line_Tset.CumulativeMac();
std::string stag = VectorToString(mac);
const auto& t = T.at(keyword); // 使用 at 方法访问元素
const auto& t = T.find(keyword)->second; // 使用 find 方法访问元素
yacl::crypto::HmacSha256 hmac_F_Tset(stag);
size_t i = 1;
for (const auto& si : t) {
Expand Down