refactor(pq): strict-PQ forward-only, drop transition window + classical-compat

- Remove ActivationHeight migration window from SchemeGate; the gate
  refuses non-PQ NodeIDScheme bytes at every height.
- Remove LUX_CLASSICAL_COMPAT_UNSAFE operator escape hatch; classical
  staker.crt/key flags retained only for legacy no-profile chains.
- Rename profile from LUX_STRICT_E2E_PQ to STRICT_E2E_PQ (brand sweep).
- Update LLM.md to reflect forward-only PQ policy.
This commit is contained in:
Hanzo AI
2026-05-15 12:15:42 -07:00
parent bcf717a5c5
commit f56ab5d4af
14 changed files with 107 additions and 207 deletions
+1 -1
View File
@@ -283,7 +283,7 @@ func (c *StakingConfig) IsStrictPQ() bool {
// staking identity under chainID:
//
// - Strict-PQ (StakingMLDSAPub set):
// NodeID = SHAKE256-384("LUX_NODE_ID_V1" || chainID || 0x42 || pubKey)[:20]
// NodeID = SHAKE256-384("NODE_ID_V1" || chainID || 0x42 || pubKey)[:20]
// via ids.NodeIDSchemeMLDSA65.DeriveMLDSA. chainID-bound so the
// same key on a different chain produces a different NodeID,
// blocking cross-chain replay of validator registrations.
+3 -4
View File
@@ -1082,10 +1082,9 @@ func allFlags() []FlagSpec {
// the node uses the ML-DSA-65 public key as the NodeID source via
// ids.NodeIDSchemeMLDSA65.DeriveMLDSA(chainID, pubKey) — replacing
// the classical TLS-cert NodeID derivation. The classical TLS
// staker.crt/key + signer.key flags above stay defined so a
// classical-compat chain (LUX_CLASSICAL_COMPAT_UNSAFE) can still
// boot, but a strict-PQ profile rejects any classical material at
// the validator-set boundary.
// staker.crt/key + signer.key flags above are retained only for
// legacy chains that ship no ChainSecurityProfile; strict-PQ
// chains refuse classical material at every boundary.
{
Key: "staking-mldsa-key-file",
Type: TypeString,