aboutsummaryrefslogtreecommitdiffhomepage
path: root/tde2e
diff options
context:
space:
mode:
authorArseny Smirnov <arseny30@gmail.com>2025-04-13 11:58:29 +0400
committerArseny Smirnov <arseny30@gmail.com>2025-04-13 11:59:30 +0400
commit71227ae7bb45712eb38eaa9b88c8ed1beac22834 (patch)
tree84ac767b50cc39a04dac3231b4d499be89f223cb /tde2e
parent69e8f49f2ebd4ed883c85e3879e330fb350d594e (diff)
e2e: adds tests for shared key validation
Diffstat (limited to 'tde2e')
-rw-r--r--tde2e/td/e2e/Blockchain.cpp10
-rw-r--r--tde2e/td/e2e/TestBlockchain.cpp4
-rw-r--r--tde2e/td/e2e/TestBlockchain.h1
-rw-r--r--tde2e/td/e2e/e2e_errors.h3
-rw-r--r--tde2e/test/blockchain.cpp82
5 files changed, 91 insertions, 9 deletions
diff --git a/tde2e/td/e2e/Blockchain.cpp b/tde2e/td/e2e/Blockchain.cpp
index 51cbf758a..139e4a3e0 100644
--- a/tde2e/td/e2e/Blockchain.cpp
+++ b/tde2e/td/e2e/Blockchain.cpp
@@ -409,25 +409,25 @@ td::Status State::clear_shared_key(const Permissions &permissions) {
}
td::Status State::validate_shared_key(const GroupSharedKeyRef &shared_key, const GroupStateRef &group_state) {
- if (shared_key->empty_shared_key()) {
+ if (shared_key->empty()) {
return td::Status::OK();
}
if (shared_key->dest_user_id.size() != shared_key->dest_header.size()) {
- return td::Status::Error("Shared key different number of users and headers");
+ return Error(E::InvalidBlock_InvalidSharedSecret, "different number of users and headers");
}
if (shared_key->dest_user_id.size() != group_state->participants.size()) {
- return td::Status::Error("Shared key has wrong number of users");
+ return Error(E::InvalidBlock_InvalidSharedSecret, "wrong number of users");
}
std::set<td::int64> participants;
for (const auto user_id : shared_key->dest_user_id) {
participants.insert(user_id);
}
if (participants.size() != shared_key->dest_user_id.size()) {
- return td::Status::Error("Shared key has duplicate users");
+ return Error(E::InvalidBlock_InvalidSharedSecret, "duplicate users");
}
for (auto &p : group_state->participants) {
if (!participants.count(p.user_id)) {
- return td::Status::Error("Unknown user_id in SetSharedKey");
+ return Error(E::InvalidBlock_InvalidSharedSecret, "unknown user_id");
}
}
return td::Status::OK();
diff --git a/tde2e/td/e2e/TestBlockchain.cpp b/tde2e/td/e2e/TestBlockchain.cpp
index 0c44ba8d3..54703c73e 100644
--- a/tde2e/td/e2e/TestBlockchain.cpp
+++ b/tde2e/td/e2e/TestBlockchain.cpp
@@ -403,7 +403,9 @@ BlockBuilder &BlockBuilder::skip_group_state_proof() {
}
BlockBuilder &BlockBuilder::with_shared_key(const std::vector<td::int64> &user_ids, bool in_changes, bool in_proof) {
- auto shared_key = make_shared_key(user_ids);
+ return with_shared_key(make_shared_key(user_ids), in_changes, in_proof);
+}
+BlockBuilder &BlockBuilder::with_shared_key(GroupSharedKeyRef shared_key, bool in_changes, bool in_proof) {
if (in_changes) {
block.changes_.push_back(Change{ChangeSetSharedKey{shared_key}});
}
diff --git a/tde2e/td/e2e/TestBlockchain.h b/tde2e/td/e2e/TestBlockchain.h
index 64fa43707..41973e0a2 100644
--- a/tde2e/td/e2e/TestBlockchain.h
+++ b/tde2e/td/e2e/TestBlockchain.h
@@ -129,6 +129,7 @@ struct BlockBuilder {
bool in_proof = true, td::int32 external_permissions = 0);
BlockBuilder &skip_group_state_proof();
BlockBuilder &with_shared_key(const std::vector<td::int64> &user_ids, bool in_changes = true, bool in_proof = true);
+ BlockBuilder &with_shared_key(GroupSharedKeyRef shared_key, bool in_changes, bool in_proof);
BlockBuilder &skip_shared_key_proof();
private:
diff --git a/tde2e/td/e2e/e2e_errors.h b/tde2e/td/e2e/e2e_errors.h
index d1168ef18..66735716e 100644
--- a/tde2e/td/e2e/e2e_errors.h
+++ b/tde2e/td/e2e/e2e_errors.h
@@ -25,6 +25,7 @@ enum class ErrorCode : int {
InvalidBlock_InvalidStateProof_Secret = 206,
InvalidBlock_NoPermissions = 207,
InvalidBlock_InvalidGroupState = 208,
+ InvalidBlock_InvalidSharedSecret = 209,
InvalidCallGroupState_NotParticipant = 300,
InvalidCallGroupState_WrongUserId = 301,
Decrypt_UnknownEpoch = 400,
@@ -68,6 +69,8 @@ inline std::string_view error_string(ErrorCode error_code) {
return "INVALID_BLOCK__INVALID_STATE_PROOF__SECRET";
case ErrorCode::InvalidBlock_InvalidGroupState:
return "INVALID_BLOCK__INVALID_GROUP_STATE";
+ case ErrorCode::InvalidBlock_InvalidSharedSecret:
+ return "INVALID_BLOCK__INVALID_SHARED_SECRET";
case ErrorCode::InvalidBlock_NoPermissions:
return "INVALID_BLOCK__NO_PERMISSIONS";
case ErrorCode::InvalidCallGroupState_NotParticipant:
diff --git a/tde2e/test/blockchain.cpp b/tde2e/test/blockchain.cpp
index 49397b088..e42d8dfe2 100644
--- a/tde2e/test/blockchain.cpp
+++ b/tde2e/test/blockchain.cpp
@@ -32,7 +32,7 @@ S_TEST(BlockchainValidation, ZeroBlock) {
.with_block_hash({})
.set_value("a", "b") // need some changes
.with_group_state({}, false, true, 7)
- .with_shared_key({}, false, true)
+ .with_shared_key(std::vector<td::int64>{}, false, true)
.build(alice_pk);
TEST_TRY_STATUS(BT().expect_ok(block));
}
@@ -141,7 +141,7 @@ S_TEST(BlockchainValidation, GroupStateChanges) {
auto zero_block =
BB().with_previous_block(minus_one_block)
.with_group_state({{1, 1, alice_pk.to_public_key()}, {2, 2, bob_pk.to_public_key()}}, true, false, 3)
- .with_shared_key({1}, true, false)
+ .with_shared_key({1, 2}, true, false)
.skip_group_state_proof()
.skip_shared_key_proof()
.build(alice_pk);
@@ -231,7 +231,7 @@ S_TEST(BlockchainValidation, GroupStateChanges) {
auto zero_block_without_external =
BB().with_previous_block(minus_one_block)
.with_group_state({{1, 1, alice_pk.to_public_key()}, {2, 2, bob_pk.to_public_key()}}, true, false, 0)
- .with_shared_key({1}, true, false)
+ .with_shared_key({1, 2}, true, false)
.skip_group_state_proof()
.skip_shared_key_proof()
.build(alice_pk);
@@ -247,5 +247,81 @@ S_TEST(BlockchainValidation, GroupStateChanges) {
.build(carol_pk);
TEST_TRY_STATUS(bt.expect_error(E::InvalidBlock_NoPermissions, block));
}
+ {
+ TEST_DEBUG_VALUE(description, "Invalid: shared key - number of users");
+ BT bt;
+ auto block =
+ BB().with_previous_block(minus_one_block)
+ .with_group_state({{1, 1, alice_pk.to_public_key()}, {2, 2, bob_pk.to_public_key()}}, true, false, 0)
+ .with_shared_key({1}, true, false)
+ .skip_group_state_proof()
+ .skip_shared_key_proof()
+ .build(alice_pk);
+ TEST_TRY_STATUS(bt.expect_error(E::InvalidBlock_InvalidSharedSecret, block));
+ }
+ {
+ TEST_DEBUG_VALUE(description, "Invalid: shared key - different number of users and headers");
+ BT bt;
+ auto keys = std::make_shared<const GroupSharedKey>(
+ GroupSharedKey{PublicKey::from_u256({}), "dummy", {1, 2}, std::vector<std::string>(3, "??")});
+ auto block =
+ BB().with_previous_block(minus_one_block)
+ .with_group_state({{1, 1, alice_pk.to_public_key()}, {2, 2, bob_pk.to_public_key()}}, true, false, 0)
+ .with_shared_key(keys, true, false)
+ .skip_group_state_proof()
+ .skip_shared_key_proof()
+ .build(alice_pk);
+ TEST_TRY_STATUS(bt.expect_error(E::InvalidBlock_InvalidSharedSecret, block));
+ }
+ {
+ TEST_DEBUG_VALUE(description, "Invalid: shared key - duplicate users");
+ BT bt;
+ auto keys = std::make_shared<const GroupSharedKey>(
+ GroupSharedKey{PublicKey::from_u256({}), "dummy", {1, 1}, std::vector<std::string>(2, "??")});
+ auto block =
+ BB().with_previous_block(minus_one_block)
+ .with_group_state({{1, 1, alice_pk.to_public_key()}, {2, 2, bob_pk.to_public_key()}}, true, false, 0)
+ .with_shared_key(keys, true, false)
+ .skip_group_state_proof()
+ .skip_shared_key_proof()
+ .build(alice_pk);
+ TEST_TRY_STATUS(bt.expect_error(E::InvalidBlock_InvalidSharedSecret, block));
+ }
+ {
+ TEST_DEBUG_VALUE(description, "Invalid: shared key - unknown users");
+ BT bt;
+ auto keys = std::make_shared<const GroupSharedKey>(
+ GroupSharedKey{PublicKey::from_u256({}), "dummy", {1, 3}, std::vector<std::string>(2, "??")});
+ auto block =
+ BB().with_previous_block(minus_one_block)
+ .with_group_state({{1, 1, alice_pk.to_public_key()}, {2, 2, bob_pk.to_public_key()}}, true, false, 0)
+ .with_shared_key(keys, true, false)
+ .skip_group_state_proof()
+ .skip_shared_key_proof()
+ .build(alice_pk);
+ TEST_TRY_STATUS(bt.expect_error(E::InvalidBlock_InvalidSharedSecret, block));
+ }
+ {
+ TEST_DEBUG_VALUE(description, "Invalid: group state - duplicate users");
+ BT bt;
+ auto block =
+ BB().with_previous_block(minus_one_block)
+ .with_group_state({{1, 1, alice_pk.to_public_key()}, {1, 2, bob_pk.to_public_key()}}, true, false, 0)
+ .skip_group_state_proof()
+ .skip_shared_key_proof()
+ .build(alice_pk);
+ TEST_TRY_STATUS(bt.expect_error(E::InvalidBlock_InvalidGroupState, block));
+ }
+ {
+ TEST_DEBUG_VALUE(description, "Invalid: group state - duplicate public key");
+ BT bt;
+ auto block =
+ BB().with_previous_block(minus_one_block)
+ .with_group_state({{1, 1, alice_pk.to_public_key()}, {2, 2, alice_pk.to_public_key()}}, true, false, 0)
+ .skip_group_state_proof()
+ .skip_shared_key_proof()
+ .build(alice_pk);
+ TEST_TRY_STATUS(bt.expect_error(E::InvalidBlock_InvalidGroupState, block));
+ }
return td::Status::OK();
}