The design from the previous commit gets its first code: strongly typed identifiers, a versioned envelope with a strict binary codec, a freshness gate that fails closed on conflicting checkpoints, a protected outbox that refuses to seal or upload before freshness confirmation, the authoritative group-state machine, real Ed25519/X25519 account identity with domain-separated signatures, an Argon2id-bounded password vault, purpose-bound AES-256-GCM local record protection with atomic snapshots, encrypted file manifests and chunk streams, and a two-stage opaque Telegram document carrier. All of it sits behind replaceable boundaries; the MLS engine itself stays deliberately unselected, and nothing here is production cryptography yet. The library lands as an OBJECT target linked into Telegram. Its cmake file has to be added by force: a bare "cmake" pattern in .gitignore swallows any new file under Telegram/cmake, and a build recipe that exists locally but never reaches the repository is exactly the kind of breakage that only shows up on someone else's machine. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
67 lines
1.8 KiB
C++
67 lines
1.8 KiB
C++
/*
|
|
This file is part of Telegram Desktop,
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
*/
|
|
#pragma once
|
|
|
|
#include "e2e_cloud/core/types.h"
|
|
|
|
#include <QtCore/QByteArray>
|
|
#include <QtCore/QString>
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <vector>
|
|
|
|
namespace E2ECloud {
|
|
|
|
inline constexpr auto kMlsCipherSuiteV1 = std::uint16_t(0x0001);
|
|
inline constexpr auto kAccountCredentialEncodedSize = 76;
|
|
|
|
struct AccountCredentialPublic {
|
|
std::uint16_t version = 1;
|
|
std::uint16_t mlsCipherSuite = kMlsCipherSuiteV1;
|
|
std::array<std::uint8_t, 32> signingPublicKey = {};
|
|
std::array<std::uint8_t, 32> archiveHpkePublicKey = {};
|
|
|
|
friend inline bool operator==(
|
|
const AccountCredentialPublic &,
|
|
const AccountCredentialPublic &) = default;
|
|
};
|
|
|
|
class Sha256Provider {
|
|
public:
|
|
virtual ~Sha256Provider() = default;
|
|
|
|
[[nodiscard]] virtual Digest digest(const QByteArray &bytes) const = 0;
|
|
|
|
};
|
|
|
|
class AccountCredentialCodecV1 final {
|
|
public:
|
|
[[nodiscard]] std::optional<QByteArray> encode(
|
|
const AccountCredentialPublic &credential) const;
|
|
[[nodiscard]] std::optional<AccountCredentialPublic> decode(
|
|
const QByteArray &bytes) const;
|
|
|
|
};
|
|
|
|
[[nodiscard]] std::optional<AccountId> DeriveAccountId(
|
|
const AccountCredentialPublic &credential,
|
|
const Sha256Provider &sha256);
|
|
[[nodiscard]] std::optional<Digest> DerivePairwiseSafetyDigest(
|
|
AccountId first,
|
|
AccountId second,
|
|
const Sha256Provider &sha256);
|
|
[[nodiscard]] std::optional<Digest> DeriveGroupSafetyDigest(
|
|
ConversationId conversationId,
|
|
AccountId ownerAccountId,
|
|
std::vector<AccountId> memberAccountIds,
|
|
const Sha256Provider &sha256);
|
|
[[nodiscard]] std::optional<QString> FormatSafetyCode(Digest digest);
|
|
|
|
} // namespace E2ECloud
|