OP-OPS-04
OP operational enforcedOperator-supplied keys. Ade supports both KES key flows: (a) Ade-native ade_node --mode key_gen_kes --out-file PATH emitting an ade.kes.seed.v1 envelope loaded via ade_runtime::producer::keys::load_ade_kes_signing_key; (b) cardano-cli node key-gen-KES emitting a 608-byte KesSigningKey_ed25519_kes_2^6 envelope loaded via ade_runtime::producer::keys::load_kes_signing_key_skey. After PHASE4-N-P S5 the cardano-cli path routes through the Ade-owned BLUE deserializer (ade_crypto::kes_sum::Sum6Kes::raw_deserialize_signing_key_kes); both flows produce a KesSecret whose inner is ade_crypto::kes_sum::Sum6Kes::SigningKey (BLUE-owned algorithm). VRF and cold (Ed25519) keys continue to be operator-supplied via cardano-cli text-envelope .skey files. Private-key material never crosses into BLUE — the entire RED custody surface lives under crates/ade_runtime/src/producer/{keys,signing,ade_kes_envelope}.rs. Wrong-size payloads fail-close via KeyLoadError::UnsupportedExpandedKesKeyFormat; structurally-invalid 608-byte payloads fail-close via KeyLoadError::KesParse(KesParseError::*). Mechanical enforcement: ci/ci_check_private_key_custody.sh + ci/ci_check_kes_envelope_closed.sh + ci/ci_check_kes_sum_compatibility.sh. OP-OPS-04-KES-PERIOD-ANCHOR (public-venue hardening): at producer-shell init the opcert.kes_period is the ABSOLUTE KES period the key's evolution-0 is certified for; the shell verifies the INJECTED current absolute period (derived from the genesis KES anchor + the durable tip slot, NEVER the raw key evolution index) is within [opcert_start, opcert_start+63], then anchors evolution-0 at opcert_start and evolves the key by (current - opcert_start) so it signs at the current period -- fail-closed KesPeriodBelowOpCertStart / KesPeriodPastOpCertEnd / KesEvolutionFailed outside the window. Signing stays RED/shell; opcert verification stays BLUE/core; no wall-clock in the deterministic shell (the period is injected).
- Source
docs/planning/phase4-n-c-invariants.md §7 (OQ1); docs/active/op-ops-04-ade-native-kes-flow.md; docs/planning/phase4-n-p-invariants.md
Enforcement trace
Code
- crates/ade_runtime/src/producer/keys.rs
- crates/ade_runtime/src/producer/ade_kes_envelope.rs
- crates/ade_runtime/src/producer/signing.rs
- crates/ade_crypto/src/kes_sum/
- crates/ade_node/src/key_gen.rs
- crates/ade_runtime/src/producer/producer_shell.rs
- crates/ade_node/src/operator_forge.rs
- crates/ade_node/src/node_lifecycle.rs
Tests 28
- ade_envelope_round_trips_through_loader_at_period_0
- ade_envelope_loader_returns_kes_at_loaded_period
- ade_envelope_loader_rejects_signing_at_past_period
- cardano_cli_kes_envelope_rejects_32_byte_payload
- cardano_cli_kes_envelope_rejects_synthetic_608_byte_payload
- cardano_cli_kes_envelope_accepts_real_608_byte_payload
- cardano_cli_kes_envelope_rejects_612_byte_payload
- cardano_cli_kes_envelope_rejects_608_byte_leaf_zero_payload
- ade_envelope_loader_returns_unknown_format
- ade_envelope_loader_returns_wrong_role
- ade_envelope_loader_returns_unsupported_crypto
- ade_envelope_loader_returns_missing_seed_32
- ade_envelope_loader_returns_period_idx_overflow
- ade_envelope_loader_returns_malformed_json
- write_ade_kes_envelope_sets_0600_permissions
- vrf_and_cold_cardano_cli_skey_envelopes_round_trip
- keys_loader_rejects_wrong_envelope_type
- keys_loader_rejects_malformed_cbor_hex
- key_load_error_io_carries_no_path_bytes
- ade_envelope_load_error_io_carries_no_path_bytes
- run_key_gen_kes_writes_loadable_envelope
- run_key_gen_kes_writes_at_loaded_period
- run_key_gen_kes_rejects_short_seed_file
- cardano_cli_corpus_skey_deserializes_and_vk_matches_ground_truth
- cardano_cli_corpus_sign_then_upstream_verifies
- shell_init_rejects_kes_period_below_opcert_start
- op_ops_04_anchors_evolution_zero_at_opcert_start_and_evolves_to_current_period
- op_ops_04_fails_closed_outside_window_passes_at_boundaries