Перейти к содержимому

PQ-подпись в TEE (2d-hsm)

Production-сеть POA использует 2d-hsm для подписи блоков. Подпись producer, кошельков агентов и моста — отдельные роли; текущие границы описаны в хранении ключей.

Здесь — обзор архитектуры сервиса. Нормативный vsock wire format описан в vsock-api-wire-format-spec-draft.md; нормативный ABI AuthorizationTicket, подписываемый preimage и правила contextHash — в authorization-tickets-precompile-spec-draft.md.

ЗадачаПримечание
PQ-подписи производителя блоковML-DSA-65 (FIPS 204) над 32-байтовым дайджестом блока на hot path (~2 с).
Подписи AuthorizationTicketКанонический ticketHash (Keccak256 + preimage как в Solidity); типы 0 recovery и 1 hard fork.
Сеть как второй факторARM_FOR_PRODUCTION требует проверенного RecentChainProof (Producer Chain Attestation v1, Ed25519) до arming.
Поверхность аттестацииGET_MEASUREMENT возвращает measurement, attestation и pq_pubkey, связанные в remote attestation.

Producer profile не реализует подпись моста. Отдельный профиль agent_gateway поддерживает POA SIGN_BRIDGE_LOCK с purpose ключа bridge operator; Ethereum bridgeOut остаётся отдельной signer/vault policy. См. хранение ключей.

Процесс хоста 2D недоверен. Он может подделывать vsock-кадры, воспроизводить старые доказательства (proof) или сообщать ложные данные о вершине (tip) цепи. Анклав обязан работать в режиме fail-closed: отклонять некорректные данные (wire format), тикеты без активации (arming), поддельные или устаревшие RecentChainProof, и отказываться подписывать без установленного ML-DSA-65 ключа.

TEE — анклав 2d-hsm

Недоверенный хост 2D

vsock: framed CBOR

Клиент хоста

enclave-protocol

состояние + vsock CBOR

ML-DSA-65

sealed при boot

Pinned ProducerAttestationTrust

Важно: ProducerAttestationTrust (Ed25519 для проверки chain proof) загружается внутри анклава из sealed config или attested provisioning. Его нельзя передавать с хоста в payload ARM_FOR_PRODUCTION.

4 байта длины (BE), байт версии протокола, байт типа сообщения, CBOR (макс. 1 MiB). Внутренние ARM / GET_STATUS / SIGN — integer map keys по спецификации.

КомандаНазначение
GET_MEASUREMENTRemote attestation + pq_pubkey + supported_ticket_types + pq_signing_ready.
ARM_FOR_PRODUCTIONArmed state после проверки RecentChainProof и согласованности measurement.
GET_STATUSМетаданные arming, pending hard fork, последний блок из proof.
SIGN_AUTHORIZATION_TICKETПодпись ticketHash; type 1 — только после arm и stateful dispatch.

Разделение диспетчеризации (dispatch) в эталонной библиотеке (crate):

  • Stateless dispatch_command — recovery (type 0) и GET_MEASUREMENT; arm / hard fork возвращают ошибку с указанием stateful path.
  • Stateful dispatch_command_with_state — arming, GET_STATUS, hard-fork signing с EnclaveState и pinned trust.
ПараметрProduction
АлгоритмML-DSA-65
pq_pubkey1952 байт
signature3309 байт (pure ML-DSA над 32-байтовым ticketHash)
Chain proofEd25519 над domain-separated preimage (v1)

pq_signing_ready: true только после успешного install_sealed_pq_signer при boot. Дефолтные сборки без вшитого секрета; до provisioning — PqSigningUnavailable. Mock-пиры: pq_signing_ready == false и 64-байтовая PQ-подпись (test-support + demo-mock-sign).

Sealed key (TASK-1): Production seal v1 — ChaCha20Poly1305 AEAD с measurement-bound ключом, производным от 32-байтового provisioning root через SHA3-256 (домен 2d-hsm-pq-seal-v1-key). Provkey root извлекается из firmware SEV-SNP через boot-helper snp-derive-root (SNP_GET_DERIVED_KEY ioctl → SHA3-256 domain-separated), записывается в /run/twod-hsm/pq-seal-root.bin при загрузке и читается анклавом через release-safe фичу platform-root-from-boot-file (фиксированный путь, не env var хоста). Формат v0 XOR — только #[cfg(test)]; вне тестов ml-dsa-65 принимает v1 и отклоняет v0. Sealing привязывается к настроенному SNP measurement. Привязка к firmware measurement сама по себе не подтверждает целостность guest kernel, диска или кода. Полноту measured boot и восстановление проверяют отдельно для конкретного deployment.

Бэкенд подписи — свойство развёрнутого build, отдельное от wire protocol: публичный ключ остаётся 1952 байта, подпись ML-DSA-65 — 3309 байт. Feature flag constant-time backend не доказывает, что пройден acceptance gate или что именно этот бэкенд работает в VM.

До заявления об устойчивости к тайминговым атакам проверьте release manifest, evidence harness dudect/ctgrind с изолированного измерительного хоста и reviewer verdict для этого build. Harness должен разделять RNG-домены генерации входов и рандомности подписи, чтобы служебный учёт не выглядел как секрет-зависимый тайминговый результат. Остаточные риски побочных каналов фиксируйте вместе с версией deployment.

enclave 2d-hsmНедоверенный хостenclave 2d-hsmНедоверенный хостGET_MEASUREMENTmeasurement, attestation, pq_pubkey, pq_signing_readyARM_FOR_PRODUCTION + RecentChainProofПроверка Ed25519 proof и pinned trustПроверка height / measurement / pubkeyarmedSIGN_AUTHORIZATION_TICKET (type 1)Требуется armed + pq_pubkey + fork fieldsподпись ML-DSA-65 + ticketHash

Hard-fork тикеты — через handle_sign_authorization_ticket_with_state после валидного arm. Recovery (type 0) может идти stateless path при bootstrap, но pq_pubkey в тикете должен совпадать с ключом анклава, если signer установлен.

Авторизация hard fork привязана к эпохе производителя, а не только к PQ-ключу. Тикет, подписанный производителем A в старой эпохе, не должен быть воспроизводим после ротации A → B → A. Поэтому on-chain/precompile сторона пересчитывает hard-fork contextHash из текущего ключа производителя и высоты его активации и отклоняет несовпадение. Эта страница остаётся архитектурным обзором; точный byte-level preimage задаёт спецификация AuthorizationTicket в репозитории 2d-hsm, ссылка выше.

Recovery производителя в native chain также ещё не является production-active функцией по умолчанию. Finalized-tip downtime gate уже есть в коде precompile 2d, но record_finalized_tip/2 пока не подключён к finality path исполнителя блоков. До этой интеграции native PRODUCER_RECOVERY остаётся fail-closed (no_finalized_tip), а не рекламируется как активный production recovery. Solidity reference моделирует это явным relay/height stand-in, а не финальным native source of truth.

В impl/rust/enclave-protocol: framing, ticketHash, cross-check с Solidity, EnclaveState, Producer Chain Attestation v1, ML-DSA-65 с production seal v1 (ChaCha20Poly1305 AEAD, measurement-bound, SNP-derived root через snp-derive-root).

Producer signing через enclave интегрирован с Elixir. Отдельно проверяются актуальность proof между arm и sign, восстановление и acceptance gate constant-time backend. Эти свойства требуют evidence для конкретного релиза.

В топологии подписантов производитель, assigned wallets агентов и bridge operator имеют раздельные роли и ключи. 2d-hsm реализует enclave-подписанты для production chain 77. Интерфейс зависит от роли: producer использует vsock, Agent Gateway — свой Unix-socket клиент. Наличие схемы или feature flag само по себе не подтверждает активный build и конфигурацию конкретной VM.