cap

package
v1.8.1 Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2026 License: BSD-3-Clause Imports: 7 Imported by: 0

Documentation

Overview

Package cap implements the ZAP capability runtime.

A Capability is a signed, attenuable token of authority. It grants a holder permission to perform a bitmask of operations on a target, with optional caveats. Caps form a chain: a parent's holder can issue an attenuated child cap whose permissions are a subset of the parent's. VerifyChain walks the chain back to a root, checking each signature, the intersection of permissions, expiry, revocation, and caveats.

Wire format is canonical ZAP — magic+version header, object data, length-prefixed list of Caveat sub-messages. The bytes are produced and read via the generated zero-copy views in capabilities_zap.go. This file is the thin idiomatic-Go wrapper that the IAM/KMS/MPC consumers see: Wrap / Cap.Field / Verifier.

Signature scope: per SPEC.md §3, the signed bytes are the canonical concatenation Capability[0..164) || canonical(Caveats) — the fixed header up to and including the Caveats list pointer, followed by each Caveat encoded as Kind:u32-LE || len(Value):u32-LE || Value in list order. This EXCLUDES the Sig field itself and the ZAP heap-area indirection bytes, and is recomputed identically by signer and verifier (see canonical.go, Cap.CanonicalBytes), so heap layout cannot be tampered with without breaking the signature and the signed bytes are identical across every language runtime.

Index

Constants

View Source
const (
	// PermAttenuate (bit 1<<32) — the holder may mint child caps whose
	// permissions are a subset of this cap's. SPEC §2.3 step 3d: a parent
	// MUST carry this bit (or be CapKindDelegate) for the verifier to
	// accept any attenuation off it.
	PermAttenuate uint64 = 1 << 32
	// PermAudit (bit 1<<33) — the holder may read the audit trail for Target.
	PermAudit uint64 = 1 << 33
	// PermRoot (bit 1<<63) — root-of-trust marker, set on root caps only.
	PermRoot uint64 = 1 << 63
)

Permission bits for Capability.Permissions (u64). Per capabilities_kinds.md "Permission bits": each CapKind owns the bottom 32 bits (their meaning is per-kind — verifiers MUST dispatch on CapKind first), and the top 32 bits are cross-cutting and identical across every CapKind.

Only the cross-cutting bits are normative wire-wide and therefore defined here; the per-kind low bits are owned by each consumer (IAM/KMS/ATS/Bridge) and declared in capabilities_kinds.md.

View Source
const AlgTagOffset = SigSize - 1

AlgTagOffset is the offset of the algorithm-tag byte within the SigSize signature footer. The byte at [SigSize-1] identifies which signature primitive a verifier MUST use; it is part of the signed payload, so a tag flip changes the signature and is caught by verifier mismatch.

View Source
const SigSize = 3408

SigSize is the fixed signature footer width in bytes. Sized at v1.1 to hold any of:

  • secp256k1 ECDSA (65 bytes)
  • Ed25519 (64 bytes)
  • ML-DSA-65 (3309 bytes, FIPS 204 §5.2 Level-3)
  • hybrid Ed25519+ML-DSA-65 (3373 bytes + 16-byte separator)

3408 is the smallest 16-byte-aligned size that fits FIPS 204 ML-DSA-65 (3309 B) with a 99-byte headroom. Schemes shorter than SigSize are zero-padded on the right; verifiers identify the scheme via the algorithm tag in the final byte (Sig[SigSize-1]) and decode the leading L_scheme bytes accordingly. See zap-spec/capabilities.zap and capabilities_kinds.md for the canonical tag table.

Variables

View Source
var (
	ErrTooShort        = errors.New("cap: buffer too short")
	ErrBadMagic        = errors.New("cap: bad magic")
	ErrBadCaveats      = errors.New("cap: caveat block malformed")
	ErrUnknownCaveat   = errors.New("cap: unknown caveat kind (fail-closed per SPEC §2.3)")
	ErrSigMismatch     = errors.New("cap: signature does not verify")
	ErrExpired         = errors.New("cap: expired")
	ErrRevoked         = errors.New("cap: revoked")
	ErrChainBroken     = errors.New("cap: chain link broken")
	ErrPermsExceedPar  = errors.New("cap: permissions exceed parent")
	ErrNotDelegable    = errors.New("cap: parent does not permit attenuation")
	ErrOpNotPermitted  = errors.New("cap: op not in permission mask")
	ErrTargetMismatch  = errors.New("cap: target does not match")
	ErrHolderMismatch  = errors.New("cap: holder does not match")
	ErrIssuerUnknown   = errors.New("cap: issuer key unknown")
	ErrCaveatViolation = errors.New("cap: caveat violated")
	// ErrUnhandledScheme means the algorithm-tag byte is one the verifier
	// does not implement (or SchemeReserved / an unknown tag). It is both
	// the value a SchemeVerify hook returns to decline a tag (so the
	// dispatcher may try its built-in ed25519 bootstrap path for
	// SchemeEd25519) AND the terminal error the dispatcher returns when no
	// path handles the tag — fail-closed per SPEC §2.3 step 3c.
	ErrUnhandledScheme = errors.New("cap: signature scheme not handled")
)

Errors returned by Wrap and chain validation.

Functions

func EncodeRevocation

func EncodeRevocation(r Revocation) []byte

EncodeRevocation marshals a Revocation into canonical ZAP wire bytes via the generated RevocationView builder. Symmetric to DecodeRevocation.

func Hash32

func Hash32(b []byte) [32]byte

Hash32 is the package's canonical 32-byte hash function. Exposed so signers and verifiers agree on the digest construction. SHA-256 is the spec-mandated CapID hash (SPEC.md §4): in every target language's stdlib, so cross-language CapIDs are trivially reproducible and the runtime stays zero-dependency. Treat the result as an opaque content identifier.

func NewCapProofView

func NewCapProofView(in CapProofViewInput) []byte

NewCapProofView builds a ZAP-encoded CapProofView message from in and returns the bytes.

func NewCapabilityView

func NewCapabilityView(in CapabilityViewInput) []byte

NewCapabilityView builds a ZAP-encoded CapabilityView message from in and returns the bytes.

func NewCaveatView

func NewCaveatView(in CaveatViewInput) []byte

NewCaveatView builds a ZAP-encoded CaveatView message from in and returns the bytes.

func NewRevocationView

func NewRevocationView(in RevocationViewInput) []byte

NewRevocationView builds a ZAP-encoded RevocationView message from in and returns the bytes.

func VerifyRevocation

func VerifyRevocation(r Revocation, issuerPub []byte) error

VerifyRevocation checks that r is a valid revocation under issuerPub using the bootstrap scheme dispatch (ed25519 mandatory-to-implement, fail-closed on unknown/reserved tags). The caller is expected to have resolved the original cap's Issuer hash to a public key (via the same IssuerKey lookup the Verifier uses) and then call this with the resolved key.

For ML-DSA-65 / hybrid / secp256k1 revocations, use Verifier.VerifyRevocation with a SchemeVerify hook wired — the package function only carries the built-in ed25519 path.

Types

type Cap

type Cap struct {
	// contains filtered or unexported fields
}

Cap is a zero-copy view over a capability buffer. Constructed by Wrap. All accessors read directly from raw without allocating; Value slices returned from CaveatAt / Caveats alias the underlying buffer.

func Attenuate

func Attenuate(parent Cap, holder [32]byte, permissions uint64, caveats []Caveat,
	expiresAt int64, signer Signer) (Cap, error)

Attenuate derives a child cap from parent by intersecting permissions and adding caveats. The child's Issuer = parent's Holder; signer must hold the parent's holder key (this is the basis for chain validation: each link is signed by the previous holder's key).

The child target equals the parent's target — attenuation never broadens scope. permissions is intersected with the parent's permissions; passing 0xFFFF... is equivalent to "inherit all". caveats are appended (not replaced); chain validation evaluates them in conjunction with the parent's.

expiresAt of 0 inherits the parent's expiry; non-zero overrides downward (the child cannot outlive the parent).

func Issue

func Issue(in Issuance, signer Signer) (Cap, error)

Issue mints a new root capability signed by signer. The signer's Public() becomes the cap's Issuer field. Parent stays as supplied (zero for a true root; non-zero for re-issuing under an existing parent at the cost of caller asserting the chain).

To derive a child cap from an existing parent, use Attenuate.

func Wrap

func Wrap(b []byte) (Cap, error)

Wrap parses a capability buffer and returns a typed zero-copy view. Validates ZAP framing (magic, version, size) plus capability-specific structural checks (sig field within bounds). Cryptographic verification lives in Verifier.

func (Cap) Bytes

func (c Cap) Bytes() []byte

Bytes returns the underlying buffer without copying.

func (Cap) CanonicalBytes added in v1.3.0

func (c Cap) CanonicalBytes() []byte

CanonicalBytes returns the exact bytes a Capability's signature is computed over, per SPEC.md §3 "Signature chain":

Capability[0..164)  ||  for each Caveat in list order:
    Kind:u32-LE || len(Value):u32-LE || Value

The fixed-header prefix is read verbatim from the wire buffer (so the signer and verifier agree on the on-wire field bytes), but the caveat section is RECOMPUTED from the decoded caveats rather than copied from the ZAP heap. This is deliberate: it excludes the heap-area pointer indirection bytes, so a tamperer cannot perturb the signature by rewriting heap layout, and it makes the signed bytes identical across language runtimes regardless of how each lays out its heap.

CanonicalBytes does NOT include Sig (bytes [164..3572)); that is the field being authenticated.

func (Cap) CaveatAt

func (c Cap) CaveatAt(i int) Caveat

CaveatAt returns the i-th caveat. Out-of-range returns a zero Caveat. The Value slice aliases the underlying buffer; callers must not mutate it. Each call re-walks the variable-element list: O(i).

func (Cap) Caveats

func (c Cap) Caveats() []Caveat

Caveats returns the slice of caveats decoded in one walk. Values alias the buffer; do not mutate.

func (Cap) ExpiresAt

func (c Cap) ExpiresAt() uint64

ExpiresAt reads the unix-second expiry. Zero means never.

func (Cap) Holder

func (c Cap) Holder() [32]byte

Holder reads the 32-byte holder hash.

func (Cap) ID

func (c Cap) ID() [32]byte

ID returns the canonical 32-byte identifier of this cap. Per SPEC.md §4 the CapID is Hash32(CanonicalBytes(cap) || Sig) — the exact bytes signed at issue time plus the signature footer. Revocation records key on ID, and the chain walk matches each child's Parent to its parent's ID, so this construction is what binds the chain.

func (Cap) IssuedAt

func (c Cap) IssuedAt() uint64

IssuedAt reads the unix-second issued-at timestamp.

func (Cap) Issuer

func (c Cap) Issuer() [32]byte

Issuer reads the 32-byte issuer hash.

func (Cap) Kind

func (c Cap) Kind() uint32

Kind reads the kind field.

func (Cap) NumCaveats

func (c Cap) NumCaveats() int

NumCaveats returns the number of caveats attached to this cap.

func (Cap) Parent

func (c Cap) Parent() [32]byte

Parent reads the 32-byte parent cap ID. Zero means root.

func (Cap) Permissions

func (c Cap) Permissions() uint64

Permissions reads the permission bitmask.

func (Cap) Signature

func (c Cap) Signature() [SigSize]byte

Signature returns the SigSize-byte signature stored in the Sig field.

func (Cap) Target

func (c Cap) Target() [32]byte

Target reads the 32-byte target hash.

type CapKind

type CapKind uint32

CapKind enumerates the kinds of authority a capability can confer.

const (
	KindReserved   CapKind = 0x00
	KindIAMSession CapKind = 0x01
	KindIAMAPIKey  CapKind = 0x02
	KindKMSAccess  CapKind = 0x10
	KindKMSSign    CapKind = 0x11
	KindMPCSign    CapKind = 0x20
	KindATSOrder   CapKind = 0x30
	KindBridgeXfer CapKind = 0x40
	KindStake      CapKind = 0x50
	KindDelegate   CapKind = 0xFF
)

type CapProofView

type CapProofView struct {
	// contains filtered or unexported fields
}

CapProofView is a zero-copy view into a ZAP-encoded CapProofView message.

func WrapCapProofView

func WrapCapProofView(b []byte) (CapProofView, error)

WrapCapProofView parses b and returns a typed view. Returns an error if the wire-level checks (magic, version, size) fail.

func (CapProofView) Chain

func (t CapProofView) Chain() zap.List

func (CapProofView) Leaf

func (t CapProofView) Leaf() CapabilityView

type CapProofViewInput

type CapProofViewInput struct {
	Leaf  []byte
	Chain [][]byte
}

CapProofViewInput collects the field values for NewCapProofView.

type CapabilityView

type CapabilityView struct {
	// contains filtered or unexported fields
}

CapabilityView is a zero-copy view into a ZAP-encoded CapabilityView message.

func WrapCapabilityView

func WrapCapabilityView(b []byte) (CapabilityView, error)

WrapCapabilityView parses b and returns a typed view. Returns an error if the wire-level checks (magic, version, size) fail.

func (CapabilityView) Caveats

func (t CapabilityView) Caveats() zap.List

func (CapabilityView) ExpiresAt

func (t CapabilityView) ExpiresAt() uint64

func (CapabilityView) Holder

func (t CapabilityView) Holder() [32]byte

func (CapabilityView) IssuedAt

func (t CapabilityView) IssuedAt() uint64

func (CapabilityView) Issuer

func (t CapabilityView) Issuer() [32]byte

func (CapabilityView) Kind

func (t CapabilityView) Kind() uint32

func (CapabilityView) Parent

func (t CapabilityView) Parent() [32]byte

func (CapabilityView) Permissions

func (t CapabilityView) Permissions() uint64

func (CapabilityView) Sig

func (t CapabilityView) Sig() [3408]byte

func (CapabilityView) Target

func (t CapabilityView) Target() [32]byte

type CapabilityViewInput

type CapabilityViewInput struct {
	Kind        uint32
	Target      [32]byte
	Holder      [32]byte
	Issuer      [32]byte
	Permissions uint64
	Parent      [32]byte
	IssuedAt    uint64
	ExpiresAt   uint64
	Caveats     [][]byte
	Sig         [3408]byte
}

CapabilityViewInput collects the field values for NewCapabilityView.

type Caveat

type Caveat struct {
	Kind  CaveatKind
	Value []byte
}

Caveat is one constraint attached to a capability. Value bytes alias the underlying ZAP buffer when produced via Cap.CaveatAt / Cap.Caveats; callers must not mutate Value in-place. Caveat literals passed into Issue/Attenuate are copied during build.

type CaveatKind

type CaveatKind uint32

CaveatKind enumerates the kinds of caveat that can be attached.

const (
	CaveatExpiresAt CaveatKind = 0x00
	CaveatMaxAmount CaveatKind = 0x01
	CaveatDestChain CaveatKind = 0x02
	CaveatRateLimit CaveatKind = 0x03
	CaveatIPCIDR    CaveatKind = 0x04
	CaveatAssetID   CaveatKind = 0x05
	CaveatOpAllow   CaveatKind = 0x06
	CaveatMaxDepth  CaveatKind = 0x07
	CaveatAudience  CaveatKind = 0x08
	CaveatNonceHash CaveatKind = 0x09
)

type CaveatView

type CaveatView struct {
	// contains filtered or unexported fields
}

CaveatView is a zero-copy view into a ZAP-encoded CaveatView message.

func WrapCaveatView

func WrapCaveatView(b []byte) (CaveatView, error)

WrapCaveatView parses b and returns a typed view. Returns an error if the wire-level checks (magic, version, size) fail.

func (CaveatView) Kind

func (t CaveatView) Kind() uint32

func (CaveatView) Value

func (t CaveatView) Value() []byte

type CaveatViewInput

type CaveatViewInput struct {
	Kind  uint32
	Value []byte
}

CaveatViewInput collects the field values for NewCaveatView.

type Ed25519Signer

type Ed25519Signer struct {
	// contains filtered or unexported fields
}

Ed25519Signer is a Signer backed by an ed25519 key. ed25519's native signature is 64 bytes; this stub places it at the leading bytes of the SigSize footer with the remaining bytes zero-padded and the algorithm tag (SchemeEd25519 = 0x02) at sig[AlgTagOffset]. The matching verifier (verifyEd25519) reads the leading 64 bytes back out and ignores the pad and tag byte.

This is intended for tests and bootstrap. Production PQ deployments plug an ML-DSA-65 Signer via a consumer's auth layer.

func NewEd25519Signer

func NewEd25519Signer() (*Ed25519Signer, error)

NewEd25519Signer generates a fresh keypair.

func (*Ed25519Signer) Public

func (s *Ed25519Signer) Public() [32]byte

Public returns the 32-byte hash of the ed25519 public key.

func (*Ed25519Signer) PublicKey

func (s *Ed25519Signer) PublicKey() ed25519.PublicKey

PublicKey returns the raw 32-byte ed25519 public key. Used in tests to register the signer with a Verifier's IssuerKey lookup.

func (*Ed25519Signer) Sign

func (s *Ed25519Signer) Sign(payload []byte) ([SigSize]byte, error)

Sign produces a 64-byte ed25519 signature placed at the leading bytes of the SigSize footer and tagged with SchemeEd25519 at AlgTagOffset.

type Issuance

type Issuance struct {
	Kind        uint32
	Target      [32]byte
	Holder      [32]byte
	Permissions uint64
	Parent      [32]byte // zero = root
	IssuedAt    int64    // 0 = use time.Now()
	ExpiresAt   int64    // 0 = no expiry
	Caveats     []Caveat
}

Issuance describes the request to mint a new root capability.

type Revocation

type Revocation struct {
	CapID      [32]byte
	RevokedAt  int64
	RevokerSig [SigSize]byte
}

Revocation is the on-the-wire record stating that a particular cap is no longer valid. Revocations are gossiped/published out-of-band; the canonical store is a hash-set keyed on CapID.

The signature is over a 40-byte canonical payload:

[32]byte CapID || uint64 RevokedAt (little-endian)

The signature occupies the SigSize footer in the same shape as cap signatures (algorithm tag at byte SigSize-1, primitive's bytes at the leading L_scheme bytes, zero pad in between) so the verifier can reuse one signing primitive. The wire encoding uses ZAP framing via the generated RevocationView; this struct is the idiomatic Go container used at the boundaries.

func DecodeRevocation

func DecodeRevocation(b []byte) (Revocation, error)

DecodeRevocation parses a ZAP-framed Revocation buffer back into the idiomatic Go struct. Returns ErrBadMagic / ErrTooShort on framing errors. Symmetric to EncodeRevocation.

func Revoke

func Revoke(c Cap, now int64, signer Signer) (Revocation, error)

Revoke produces a Revocation record signed by signer. The signer must be the cap's original issuer — only the issuer (or a delegated revocation authority, out of scope here) can revoke a cap.

type RevocationView

type RevocationView struct {
	// contains filtered or unexported fields
}

RevocationView is a zero-copy view into a ZAP-encoded RevocationView message.

func WrapRevocationView

func WrapRevocationView(b []byte) (RevocationView, error)

WrapRevocationView parses b and returns a typed view. Returns an error if the wire-level checks (magic, version, size) fail.

func (RevocationView) CapID

func (t RevocationView) CapID() [32]byte

func (RevocationView) RevokedAt

func (t RevocationView) RevokedAt() uint64

func (RevocationView) RevokerSig

func (t RevocationView) RevokerSig() [3408]byte

type RevocationViewInput

type RevocationViewInput struct {
	CapID      [32]byte
	RevokedAt  uint64
	RevokerSig [3408]byte
}

RevocationViewInput collects the field values for NewRevocationView.

type Scheme added in v1.1.0

type Scheme uint8

Scheme is the wire-level signature algorithm tag. The numeric values MUST match capabilities_kinds.md "Wire schemes" table; the byte written at Sig[AlgTagOffset] is one of these constants.

Verifiers fail-closed on SchemeReserved and on values not enumerated here. A consumer's auth layer may re-export a typed alias whose constants reuse these numeric values one-for-one so the wire byte and the typed enum agree.

const (
	// SchemeReserved (0x00) MUST NOT appear in valid caps. Verifiers
	// reject it so a zero-filled / never-initialised footer is caught.
	SchemeReserved Scheme = 0x00
	// SchemeSecp256k1 is 65-byte secp256k1 ECDSA (R||S||v).
	SchemeSecp256k1 Scheme = 0x01
	// SchemeEd25519 is 64-byte Ed25519 (RFC 8032).
	SchemeEd25519 Scheme = 0x02
	// SchemeMLDSA65 is the 3309-byte FIPS 204 Level-3 ML-DSA-65 signature.
	SchemeMLDSA65 Scheme = 0x03
	// SchemeHybrid is concatenated Ed25519 || ML-DSA-65 (64 + 3309 = 3373 B).
	SchemeHybrid Scheme = 0x04
)

type Signer

type Signer interface {
	// Sign returns a fixed-size signature over the supplied payload.
	// The signature MUST verify under the Public() key on the verifier
	// side. Implementations SHOULD be deterministic per call for
	// replay-debugging and MUST NOT leak the secret key. The final
	// byte (sig[AlgTagOffset]) MUST carry the algorithm tag.
	Sign(payload []byte) ([SigSize]byte, error)

	// Public returns the canonical 32-byte hash of the signer's public
	// key. This must match the cap's Issuer field for Verify to accept
	// the signature.
	Public() [32]byte
}

Signer abstracts the issuer's signing key. The v1.1 wire format's signature footer (SigSize bytes, see cap.go) is wide enough for any supported primitive: secp256k1 ECDSA (65 B), Ed25519 (64 B), or ML-DSA-65 (3309 B per FIPS 204 §5.2). Implementations write their scheme tag at sig[AlgTagOffset] before signing so verifiers can dispatch on it.

This package only requires the interface; concrete signers live in a consumer's auth layer where the appropriate crypto dependency is wired in. The Ed25519Signer stub below is provided for tests and bootstrap.

type Verifier

type Verifier struct {
	IsRevoked    func(capID [32]byte) bool
	IssuerKey    func(issuerHash [32]byte) ([]byte, error)
	SchemeVerify func(scheme Scheme, pub []byte, payload []byte, sig [SigSize]byte) error
}

Verifier holds the policy dependencies cap validation needs:

  • IsRevoked is a side-channel lookup against the revocation list. Return true to reject the cap regardless of signature or expiry. A nil func is treated as "nothing revoked".

  • IssuerKey resolves an issuer's 32-byte hash back to its raw public key bytes (ed25519 raw pubkey or ML-DSA-65 FIPS 204 encoding). Must return ErrIssuerUnknown for unknown issuers.

  • SchemeVerify dispatches on the algorithm-tag byte at sig[AlgTagOffset] to validate the signature under the right primitive. A nil func means ed25519-only: a SchemeEd25519 tag uses the built-in bootstrap verifier and every other tag (including SchemeReserved / unknown) is refused fail-closed. Consumers that want ML-DSA-65 / hybrid / secp256k1 wire a hook; returning ErrUnhandledScheme from it for SchemeEd25519 falls back to the bootstrap path, so callers need not special-case the bootstrap.

func (Verifier) Verify

func (v Verifier) Verify(c Cap, now int64) error

Verify validates a single cap independent of chain context. Checks:

  • signature is valid for the cap's Issuer (signed payload = CanonicalBytes per SPEC §3: Capability[0..164) || canonical(Caveats))
  • not expired at the supplied now (unix seconds)
  • not revoked
  • caveat list parses cleanly

Returns nil if the cap is acceptable. Note that Verify does NOT walk the parent chain — use VerifyChain for that. A cap that passes Verify is structurally sound but may still be useless if its parent is revoked or its permissions don't include the op being attempted.

func (Verifier) VerifyChain

func (v Verifier) VerifyChain(leaf Cap, chain []Cap, op uint64, target [32]byte,
	holder [32]byte, now int64) error

VerifyChain validates a cap proof end-to-end:

  • leaf has not expired, is not revoked, has a valid signature
  • leaf grants op (bit set in Permissions)
  • leaf grants target (matches the supplied target)
  • leaf grants holder (matches the supplied holder)
  • chain links each parent ID to the next cap in chain
  • every link verifies (signature, expiry, revocation)
  • every link's permissions are a superset of the child's
  • the root link (chain[len-1]) has Parent == zero
  • caveats are walked at each level

Pass chain as parents nearest-to-leaf first: chain[0] is the leaf's parent, chain[len-1] is the root. An empty chain means leaf is a root (and the function only checks the leaf itself).

func (Verifier) VerifyRevocation added in v1.3.0

func (v Verifier) VerifyRevocation(r Revocation, issuerPub []byte) error

VerifyRevocation checks that r is a valid revocation under issuerPub, dispatching on the algorithm tag in r.RevokerSig[AlgTagOffset] exactly as cap signatures do (B4: scheme-aware, not hardcoded ed25519). The dispatch is fail-closed (SPEC §2.3 step 3c): a tag the verifier does not implement, or SchemeReserved (0x00), is rejected. Wire a SchemeVerify hook on the Verifier to accept ML-DSA-65 / hybrid / secp256k1 revocations.

Jump to

Keyboard shortcuts

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