keyera

package
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package keyera is the lifecycle wrapper for a Lens group lineage.

One KeyEra is opened by Bootstrap (a one-time foundation MPC ceremony at chain genesis or governance-gated Reanchor). The trust is confined to genesis of that key era. Subsequent validator-set rotations call Reshare, which preserves the GroupKey (G, H, X) and rotates only the share distribution; no trusted dealer is needed for resharing. Reanchor opens a new era with a fresh GroupKey for security-event response (rare, governance-gated).

The single source of truth for the lifecycle is `lens/DESIGN.md` (in concept; see also pulsar/DESIGN.md and lps/LP-103-lens.md).

Invariants (enforced loudly):

BLS lane:    each validator has its OWN keypair.
ML-DSA lane: each validator has its OWN keypair.
Lens lane:   each validator has a SHARE of one group key.
Pulsar lane: each validator has a SHARE of one group key.

Within a key era:

  • The same hidden signing secret s is preserved across epochs.
  • The same group public key X = s·G is preserved.
  • G and H are curve constants; they never change within or across eras of the same curve.
  • Only the share distribution of s rotates per epoch.

Across key eras (Reanchor): X is fresh, s is fresh.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUninitialized    = errors.New("keyera: era is uninitialized")
	ErrInvalidThreshold = errors.New("keyera: threshold must satisfy 1 <= t <= n")
	ErrEmptyValidators  = errors.New("keyera: validator set is empty")
	ErrMissingShare     = errors.New("keyera: share missing for validator")
)

Errors returned by the package.

Functions

This section is empty.

Types

type EpochShareState

type EpochShareState struct {
	// Lineage (changes only at Reanchor).
	KeyEraID uint64

	// HashSuiteID is the pinned hash profile for this share state.
	// Mirrored from the parent KeyEra at Bootstrap and propagated
	// without modification through every Reshare. Reanchor opens a
	// NEW era which MAY pin a different value.
	HashSuiteID string

	// LSS lifecycle.
	Generation   uint64
	RollbackFrom uint64

	// Per-epoch state (rotates every Refresh / Reshare).
	Epoch      uint64
	Validators []string
	Threshold  int
	Shares     map[string]*threshold.KeyShare
}

EpochShareState is the per-epoch share distribution for a key era.

Three lineage fields, kept distinct (do not collapse — they mean different things):

  • KeyEraID: Lens group-key lineage. Bumps only at Reanchor (fresh GroupKey).
  • Generation: LSS resharing version within this key era. Bumps every Refresh / Reshare under the same GroupKey.
  • RollbackFrom: nonzero only when this state descends from a Rollback (= the prior Generation that was reverted from). Zero on ordinary forward transitions.

type KeyEra

type KeyEra struct {
	EraID        LensKeyEraID
	GroupID      LensGroupID
	GroupKey     *threshold.GroupKey
	GenesisEpoch uint64
	HashSuiteID  string
	State        *EpochShareState
}

KeyEra is one Lens group lineage. The GroupKey (G, H, X) is set at Bootstrap and persists across every Reshare within the era. State is the current epoch's share distribution; it rotates each Reshare.

HashSuiteID pins the hash profile this era was opened under. It is recorded at Bootstrap and remains immutable through every Reshare in the era (per pulsar/proofs/hash-suite-separation.tex Remark on era-pinning, mirrored on the curve-side sister kernel). Reanchor MAY change the suite for the new era. The field is read-only after Bootstrap returns; Reshare propagates it without parameterisation.

func Bootstrap

func Bootstrap(
	c primitives.Curve,
	t int,
	validators []string,
	groupID LensGroupID,
	eraID LensKeyEraID,
	entropy io.Reader,
) (*KeyEra, error)

Bootstrap runs the one-time trusted-dealer ceremony at chain genesis or governance-gated Reanchor.

The trust is confined to genesis of the key era: the dealer momentarily knows the master secret s while constructing the shares. If s is retained, copied, or exfiltrated, the long-lived Lens group key is compromised. Foundation MUST coordinate Bootstrap as a publicly observable MPC ceremony at chain launch.

After Bootstrap returns, the master secret no longer exists in the dealer's memory. The chain only has the public GroupKey and the distributed shares.

Use crypto/rand.Reader for the kernel's randomness when no specific ceremony source is provided. Tests pass a deterministic source.

Bootstrap pins the production HashSuite (Lens-SHA3). Use BootstrapWithSuite to open an era under the legacy Lens-BLAKE3 profile (for cross-suite KAT replay only — NOT for production).

func BootstrapWithSuite

func BootstrapWithSuite(
	c primitives.Curve,
	suite hash.HashSuite,
	t int,
	validators []string,
	groupID LensGroupID,
	eraID LensKeyEraID,
	entropy io.Reader,
) (*KeyEra, error)

BootstrapWithSuite is the canonical entrypoint that explicitly pins the hash profile this era will run under. The supplied suite is recorded on the returned KeyEra and propagates unchanged through every Reshare; Reanchor opens a fresh era and MAY pin a different suite. Pass nil to use the production default (Lens-SHA3).

func Reanchor

func Reanchor(
	prev *KeyEra,
	c primitives.Curve,
	t int,
	validators []string,
	groupID LensGroupID,
	entropy io.Reader,
) (*KeyEra, error)

Reanchor opens a new key era with a fresh GroupKey. Use ONLY for security-event response — long-tail share leakage, suspected master-secret compromise, etc. The chain governance MUST authorize this; it is not a routine operation.

Reanchor inherits the prior era's HashSuiteID. To migrate to a different suite (e.g. moving from legacy Lens-BLAKE3 to production Lens-SHA3) call ReanchorWithSuite.

func ReanchorWithSuite

func ReanchorWithSuite(
	prev *KeyEra,
	c primitives.Curve,
	suite hash.HashSuite,
	t int,
	validators []string,
	groupID LensGroupID,
	entropy io.Reader,
) (*KeyEra, error)

ReanchorWithSuite opens a new key era with a fresh GroupKey under the supplied HashSuite. Reanchor is the ONLY lifecycle entrypoint that may pin a hash profile different from the prior era's (Reshare cannot — that is enforced by Reshare not accepting a suite parameter). nil suite resolves to the production default.

func (*KeyEra) Reshare

func (era *KeyEra) Reshare(
	newValidators []string,
	newThreshold int,
	randSource io.Reader,
) (*EpochShareState, error)

Reshare evolves the era to a new committee while preserving GroupKey.

The bare Shamir kernel runs in-process; for distributed deployments the consensus layer wraps this in the full Verifiable Secret Resharing exchange (commits, complaints, activation cert) defined in lens/reshare. This kernel exists to (a) drive the cryptographic core, (b) be reused as the trusted-collaborator path for single-process integration tests, and (c) provide a reference against which the distributed protocol can be byte-equality checked.

rand defaults to crypto/rand.Reader.

type LensGroupID

type LensGroupID uint64

LensGroupID identifies one Lens group for grouped Quasar setups where validator sets are partitioned into smaller groups, each with its own GroupKey lineage. For the single-group case it is zero.

type LensKeyEraID

type LensKeyEraID uint64

LensKeyEraID is a monotonically increasing identifier for a key era. Bumped only on Reanchor (rare governance event). All resharings within an era keep the same era ID.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL