PQ-подпись в TEE (2d-hsm)
Основная сеть POA использует 2d-hsm для подписи блоков. Подпись производителя блоков, кошельков агентов и моста — отдельные роли; текущие границы описаны в хранении ключей.
Здесь — обзор архитектуры сервиса. Нормативный формат сообщений vsock описан в vsock-api-wire-format-spec-draft.md; нормативный ABI AuthorizationTicket, подписываемое сообщение и правила contextHash — в authorization-tickets-precompile-spec-draft.md.
Зона ответственности анклава
Заголовок раздела «Зона ответственности анклава»| Задача | Примечание |
|---|---|
| PQ-подписи производителя блоков | ML-DSA-65 (FIPS 204) над 32-байтовым дайджестом блока при формировании блока. |
Подписи AuthorizationTicket | Канонический ticketHash (Keccak256 + preimage как в Solidity); тип 0 для восстановления и тип 1 для хардфорка. |
| Сеть как второй фактор | ARM_FOR_PRODUCTION требует проверенного RecentChainProof (Producer Chain Attestation v1, Ed25519) до активации подписи. |
| Поверхность аттестации | GET_MEASUREMENT возвращает measurement, attestation и pq_pubkey, данные для удалённой аттестации. |
Профиль производителя блоков не реализует подпись моста. Отдельный профиль agent_gateway поддерживает POA SIGN_BRIDGE_LOCK с отдельным назначением ключа оператора моста; Ethereum bridgeOut остаётся отдельной политикой подписанта и vault. См. хранение ключей.
Граница доверия хост ↔ анклав
Заголовок раздела «Граница доверия хост ↔ анклав»Хост считается недоверенным. Он может подделывать vsock-кадры, воспроизводить старые доказательства (proof) или сообщать ложные данные о вершине (tip) цепи. Анклав обязан отказывать при невозможности подтвердить условия безопасности: отклонять некорректные данные (wire format), тикеты без активации (arming), поддельные или устаревшие RecentChainProof, и отказываться подписывать без установленного ML-DSA-65 ключа.
Важно: ProducerAttestationTrust (Ed25519 для проверки chain proof) загружается внутри анклава из запечатанной конфигурации или при выдаче конфигурации с проверкой аттестации. Его нельзя передавать с хоста в данных запроса ARM_FOR_PRODUCTION.
Команды vsock (v1)
Заголовок раздела «Команды vsock (v1)»4 байта длины (BE), байт версии протокола, байт типа сообщения, CBOR (макс. 1 MiB). Внутренние ARM / GET_STATUS / SIGN — целочисленные ключи CBOR-структур согласно спецификации.
| Команда | Назначение |
|---|---|
GET_MEASUREMENT | Данные удалённой аттестации + pq_pubkey + supported_ticket_types + pq_signing_ready. |
ARM_FOR_PRODUCTION | Переход в состояние готовности к подписи после проверки RecentChainProof и согласованности измерения среды. |
GET_STATUS | Состояние активации, ожидающий хардфорк и последний блок из подтверждения цепи. |
SIGN_AUTHORIZATION_TICKET | Подпись ticketHash; тип 1 — только после активации и обработки с учётом состояния. |
Разделение диспетчеризации (dispatch) в эталонной библиотеке (crate):
- Без состояния
dispatch_command— восстановление (тип 0) иGET_MEASUREMENT; активация / хардфорк возвращают ошибку с требованием обработки с учётом состояния. - С состоянием
dispatch_command_with_state— активация,GET_STATUS, подпись хардфорка сEnclaveStateи закреплёнными доверенными ключами.
Криптопрофиль
Заголовок раздела «Криптопрофиль»| Параметр | Рабочий профиль |
|---|---|
| Алгоритм | ML-DSA-65 |
pq_pubkey | 1952 байт |
signature | 3309 байт (режим pure ML-DSA над 32-байтовым ticketHash) |
| Подтверждение цепи | Ed25519 над сообщением с отдельным доменом подписи (v1) |
pq_signing_ready: true только после успешного install_sealed_pq_signer при загрузке. Сборки по умолчанию не содержат секрета; до установки ключа возвращается PqSigningUnavailable. Тестовые имитации подписанта: pq_signing_ready == false и 64-байтовая PQ-подпись (test-support + demo-mock-sign).
Запечатанный ключ (TASK-1): Production seal v1 — ChaCha20Poly1305 AEAD с ключом, привязанным к измерению среды, производным от 32-байтового корня выдачи ключей через SHA3-256 (домен 2d-hsm-pq-seal-v1-key). Корневой материал извлекается из прошивки SEV-SNP через загрузочный компонент snp-derive-root (SNP_GET_DERIVED_KEY ioctl → SHA3-256 domain-separated), записывается в /run/twod-hsm/pq-seal-root.bin при загрузке и читается анклавом через возможность сборки platform-root-from-boot-file (фиксированный путь, не переменная окружения хоста). Формат v0 XOR — только #[cfg(test)]; вне тестов ml-dsa-65 принимает v1 и отклоняет v0. Запечатывание привязано к настроенному измерению SNP. Привязка к измерению прошивки сама по себе не подтверждает целостность ядра гостевой системы, диска или кода. Полноту измеряемой загрузки и восстановление проверяют отдельно для конкретного развёртывания.
Проверка устойчивости к тайминговым атакам
Заголовок раздела «Проверка устойчивости к тайминговым атакам»Реализация подписи определяется развёрнутой сборкой, отдельно от формата протокола: публичный ключ остаётся 1952 байта, подпись ML-DSA-65 — 3309 байт. Наличие флага реализации с постоянным временем выполнения не доказывает, что она прошла приёмку или используется в данной VM.
До заявления об устойчивости к тайминговым атакам проверьте манифест релиза, результаты dudect/ctgrind на изолированном измерительном хосте и заключение ревью для этой сборки. Измерительный стенд должен использовать раздельные источники случайности для входных данных и подписи, чтобы служебный учёт не выглядел как зависимость времени выполнения от секретных данных. Остаточные риски побочных каналов фиксируйте вместе с версией развёртывания.
Активация подписи и хардфорк
Заголовок раздела «Активация подписи и хардфорк»Тикеты хардфорка — через handle_sign_authorization_ticket_with_state после успешной активации. Восстановление (тип 0) может обрабатываться без состояния при начальной настройке, но pq_pubkey в тикете должен совпадать с ключом анклава, если подписант установлен.
Авторизация хардфорка привязана к эпохе производителя, а не только к PQ-ключу. Тикет, подписанный производителем A в старой эпохе, не должен быть воспроизводим после ротации A → B → A. Поэтому прекомпайл сети пересчитывает contextHash хардфорка из текущего ключа производителя и высоты его активации и отклоняет несовпадение. Эта страница остаётся архитектурным обзором; точный побайтовый формат подписываемого сообщения задаёт спецификация AuthorizationTicket в репозитории 2d-hsm, ссылка выше.
Восстановление производителя в нативной сети пока не включено по умолчанию для основной сети. Проверка простоя по последнему финализированному блоку уже есть в коде прекомпайла 2d, но record_finalized_tip/2 пока не подключён к обработке финальности в исполнителе блоков. До этой интеграции нативный PRODUCER_RECOVERY отклоняется (no_finalized_tip) и не считается доступным механизмом восстановления основной сети. Эталонная реализация Solidity использует явную модель передачи высоты; она не заменяет источник финальности нативной сети.
Статус реализации
Заголовок раздела «Статус реализации»В impl/rust/enclave-protocol реализованы обрамление сообщений, ticketHash, сверка с Solidity, EnclaveState, Producer Chain Attestation v1 и ML-DSA-65 с production seal v1. Запечатывание использует ChaCha20Poly1305 AEAD, привязку к измерению среды и корень SEV-SNP через snp-derive-root.
Подпись блоков в анклаве интегрирована с Elixir. Отдельно проверяются актуальность подтверждения цепи между активацией и подписью, восстановление и приёмка реализации с постоянным временем выполнения. Эти свойства требуют подтверждений для конкретного релиза.
Связь с топологией моста
Заголовок раздела «Связь с топологией моста»В топологии подписантов производитель, кошельки агентов и оператор моста имеют раздельные роли и ключи. 2d-hsm реализует подписанты в анклаве для основной сети 77. Интерфейс зависит от роли: производитель использует vsock, Agent Gateway — свой Unix-socket клиент. Наличие схемы или флага настройки само по себе не подтверждает активную сборку и конфигурацию конкретной VM.