Commit Graph
7 Commits
Author SHA1 Message Date
zeekay 0144f80def consensus: collapse profile registry to strict / permissive / fips
PQ mode is binary. The profile registry is collapsed to three
canonical bundles:

  0x01 ProfileStrictPQ   ("STRICT")     — production PQ chains
  0x02 ProfilePermissive ("PERMISSIVE") — testnet / devnet
  0x03 ProfileFIPS       ("FIPS")       — FIPS-aligned superset

Removed pseudo-profiles: HybridProfile, ClassicalProfile, BLSProfile,
ZooStrictPQProfile, HanzoStrictPQProfile, QuasarStrictPQProfile,
AnnulusStrictPQProfile. Chains that need classical primitives pin
ForkClassicalCompatUnsafeProfile (0x80) at the byte layer and own
the audit consequence.

(*ChainSecurityProfile).IsPQ() is the single canonical predicate.
Profile string surface tracks the byte registry exactly: "strict",
"permissive", "fips".

Cross-brand scrub: dropped "Hanzo mesh" doc-comments in pq_mode.go
+ pq_mode_test.go + witness_floor_test.go in favor of "Lux mesh".
Dropped Lux/Zoo/Hanzo enumeration in account_id.go. account_id_test.go
uses fork byte (0x80) instead of zoo/hanzo profile IDs. qblock.go
references LP-0079 instead of cross-org HIP path.
2026-05-11 18:03:55 -07:00
zeekay dbc5f30a8a config: collapse to one strict-PQ profile
Kill ProfileZooStrictPQ (0x04) and ProfileHanzoStrictPQ (0x05). They
were byte-identical to StrictPQ except for ProfileID + ProfileName —
which makes them not a different profile, just a different label on
the same crypto. Chain identity comes from chain genesis (chain ID,
network ID, NodeID set), not from a sibling profile byte.

One strict-PQ, one way:
  ProfileStrictPQ      (0x01)
  ProfilePermissive    (0x02)
  ProfileFIPS          (0x03)

Removed: ZooStrictPQProfile var, HanzoStrictPQProfile var, ZooStrictPQ()
constructor, HanzoStrictPQ() constructor, strictPQProfileTemplate()
helper, ProfileNameZooStrictPQ const, ProfileNameHanzoStrictPQ const,
ProfileByID switch arms, IsPQ() switch arms, validatePolicy class-
membership arms, witness.go BLS-aggregate-forbid arms, contract_profile.go
classical-refusal arms, parity_with_auth_test cases.

Test inputs that previously used 43114/43113 (Avalanche chain IDs leaked
into test data) now use 96369/96368 (Lux mainnet/testnet) — no cross-
brand contamination in canonical Lux repos.

White-label chains (Hanzo at ~/work/hanzo/node, Zoo at ~/work/zoo/node)
each have their own chain genesis and select ProfileStrictPQ for their
PQ mode; they don't need a sibling profile byte.
2026-05-11 17:19:02 -07:00
zeekay c40e832a9e consensus: drop Quasar/Annulus/Lux from profile identifiers
First-principles cleanup: family names (Quasar, Annulus) and the Lux
brand prefix belong in papers/docs, not Go identifiers. Canonical names:

  ProfileLuxStrictPQ    -> ProfileStrictPQ
  ProfileLuxPermissive  -> ProfilePermissive
  ProfileLuxFIPS        -> ProfileFIPS
  QuasarStrictPQ()      -> removed (was 0x06 byte-identical to 0x01)
  AnnulusStrictPQ()     -> removed (was alias for the above)
  ProfileNameLuxStrictPQ etc. -> removed

ProfileZooStrictPQ (0x04) and ProfileHanzoStrictPQ (0x05) kept — chain-
specific siblings, not crypto family branding. Wire-format cSHAKE256
customization tags (LUX_PQ_PERMIT_V1 etc.) intentionally stay brand-
prefixed as domain separators.

IsPQ(), ProfileByID(), validatePolicy() switches updated.
ProfileName strings drop LUX_ prefix: "LUX_STRICT_PQ" -> "STRICT_PQ".
Golden ProfileHash in security_profile_e2e_pq_test.go re-pinned.
2026-05-11 16:50:46 -07:00
zeekay b937576be3 consensus/config: Quasar = stack, Annulus = boundary (ProfileID 0x06)
Canonical naming locked in:
  ProfileQuasarStrictPQ  = 0x06         (canonical byte)
  ProfileNameQuasarStrictPQ = "QUASAR_STRICT_PQ"

Legacy aliases preserved so downstream chain configs and existing
tests keep building (no breaking change):
  ProfileAnnulusStrictPQ     = ProfileQuasarStrictPQ
  ProfileNameAnnulusStrictPQ = ProfileNameQuasarStrictPQ
  ProfileNameLuxStrictPQ     = ProfileNameQuasarStrictPQ
  AnnulusStrictPQ() returns QuasarStrictPQ()

Quasar is the Lux PQ stack; Annulus is its strict-PQ enforcement
ring -- the boundary that excludes classical crypto and enforces
SHA3_NIST, ML-DSA, Pulsar finality, STARK/FRI proofs, ML-KEM
networking, and fail-closed verification. Toolkits remain
configurable for forks; the Annulus boundary itself is fail-closed.

config tests: ok 0.284s.
2026-05-11 15:40:21 -07:00
zeekay 21d564c34b consensus/auth: canonical KEM scheme numbering via config.KeyExchangeID (Bug 3)
Before: protocol/auth/scheme_ids.go declared its own KeyExchangeID type
with values 0x52/0x53 — disjoint from config/pq_mode.go (0x01/0x02) and
node/network/kem/scheme.go (0x62/0x63). Three packages, three numberings
of the same primitive.

After: auth.KeyExchangeID is a type alias of config.KeyExchangeID. The
canonical wire bytes (0x01 = ML-KEM-768, 0x02 = ML-KEM-1024, 0x90 =
X25519Unsafe) live in config and are re-exported by auth. Methods
(String, IsPostQuantum, IsForbiddenInPQMode) are inherited from config.

Dropped: KeyExchangeMLKEM512 (NIST Cat 1, below strict-PQ floor; never
deployed) and KeyExchangeX25519Legacy (renamed to X25519Unsafe to match
config). No production code referenced these.

New test (auth_test package): TestKEMSchemeIDs_AllUseCanonicalNumbering
proves auth's exported KeyExchange* constants are byte-identical to
config's, with wire bytes 0x01 / 0x02 / 0x90.
2026-05-11 09:29:31 -07:00
zeekay 175a787c5f consensus/auth: canonical DeriveAccountID matches registry (Bug 2)
Before: protocol/auth/account_id.go::DeriveAccountID used customization
"LUX_ACCOUNT_V1" with inputs (chainID, scheme, pubkey). Registry's
DeriveAccountID used "LUX_ACCOUNT_ID_V1" with (profileID, chainID,
scheme, compactPubkey). Same wallet → different 48-byte AccountIDs
across the two paths; the Z-Chain registry would reject every tx
originated by a properly-registered wallet via ErrTxAuthAccountIDMismatch.

After: auth's signature is (profileID, chainID, scheme, compactPubkey)
under "LUX_ACCOUNT_ID_V1" — byte-for-byte identical to registry's
output for identical inputs. The new ProfileID prefix closes the
cross-profile replay class (same wallet on LuxStrictPQ vs LuxFIPS
yields distinct AccountIDs).

Wire change: forward-only. The previous "LUX_ACCOUNT_V1" path was never
deployed to a live chain. VerifyTxAuthEnvelope rebinds via env.ProfileID
which the envelope already carries.

New tests:
  protocol/zchain/registry (external test pkg):
    TestDeriveAccountID_MatchesRegistryDerivation — auth & registry
      produce identical 48-byte outputs across four (profile, chain,
      scheme, pubkey) tuples (Lux/Zoo/Hanzo strict-PQ + Lux-permissive).
    TestDeriveAccountID_CustomizationTagsMatch — pins
      registry.AccountIDCustomization = "LUX_ACCOUNT_ID_V1".

  protocol/auth (account_id_test.go rewrites):
    TestDeriveAccountID_DistinctProfilesSameKey — five profiles
      produce five distinct AccountIDs for the same wallet.
    Existing chain/scheme/key-separation tests rewritten under the
      new four-arg signature.
2026-05-11 09:20:23 -07:00
zeekayandGitHub 727a87d4a2 consensus: protocol/auth — TxAuthEnvelope + PQPermit + ContractAuthProfile (#2)
Adds the canonical PQ authorization surface for the user-facing layers:
  - protocol/auth/tx_envelope.go  — TxAuthEnvelope + SigningDigest +
    VerifyTxAuthEnvelope; binds wallet scheme, hash suite, account ID,
    nonce, expiry, fee policy, call root via TupleHash256
    "LUX_TX_AUTH_V1"
  - protocol/auth/permit.go        — PQPermit (replaces EIP-2612) with
    TupleHash256 "LUX_PQ_PERMIT_V1"
  - protocol/auth/contract_profile.go — per-contract auth declaration
    (admin / upgrade / pause / permit scheme)
  - protocol/auth/account_id.go    — SHAKE256-384 PQ AccountID derivation
  - protocol/auth/precompile.go    — EVM precompile contracts for native
    PQ verify (wiring into coreth is a follow-up)

Local WalletSchemeID / TxSchemeID / ContractAuthID / KeyExchangeID /
RecoverySchemeID declared as temporary types in protocol/auth/scheme_ids.go;
the parallel ChainSecurityProfile expansion agent's canonical types in
config/ will replace them via type aliases on merge.

Patch-bump.
2026-05-10 21:31:51 -07:00