transparency

package
v0.1.66 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package transparency is the key transparency log for token issuer keys, ported from eat-pass core/src/transparency.rs and wire-compatible with it (domain strings, leaf/chain/sth hashing, JSON field names, FAEST-128f signed heads — verified against a reference-generated vector in testdata/).

Pinning one issuer key begs the question of how a client learns the right key and notices a silent rotation to an attacker key. The answer is a small, gossip-able append-only log: the operator publishes a hash-chained list of KeyRecords — one per issuer key it has ever vouched for — and a FAEST-128f SignedHead over the chain head. Clients pin the log's public key (one key, long-lived) instead of every issuer key, then run three checks: VerifyLog (the served records reproduce the signed head), VerifyInclusion (the key the issuer is serving is in the log), and, across time, VerifyConsistency (the new head extends the previously seen one — history was appended to, never rewritten).

This is a deliberately linear hash chain rather than an RFC 6962 Merkle tree: issuer keys rotate rarely (tens of records), so shipping the whole record list is cheap and the proofs are trivial to audit by hand.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrHeadMismatch  = errors.New("signed head does not match the served records")
	ErrBadSignature  = errors.New("signed-head signature invalid")
	ErrNotIncluded   = errors.New("token_key_id not present in the log")
	ErrNotConsistent = errors.New("new log does not extend the previously-seen head (history rewritten)")
)

Errors mirroring the reference TransparencyError variants.

Functions

func HeadOf

func HeadOf(records []KeyRecord) ([32]byte, error)

HeadOf is the head over records (genesis if empty).

func VerifyConsistency

func VerifyConsistency(old SignedHead, newRecords []KeyRecord) error

VerifyConsistency is client check #3, across time: newRecords extend the previously seen old head — the old head reappears as the intermediate head after old.Seq. Detects an operator that rewrites earlier records. Call VerifyLog on the new pair first.

func VerifyInclusion

func VerifyInclusion(records []KeyRecord, tokenKeyID [32]byte) (uint64, error)

VerifyInclusion is client check #2: the issuer key the client is about to use is present in the verified log (call VerifyLog first). Returns the record seq.

func VerifyLog

func VerifyLog(logPub [32]byte, records []KeyRecord, sth SignedHead) error

VerifyLog is client check #1: the served records reproduce the signed head, and the head is genuinely signed by the pinned log key. After this returns nil, the records are exactly what the operator committed to.

Types

type KeyLog

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

KeyLog is the operator-side builder for the append-only log.

func NewKeyLog

func NewKeyLog() *KeyLog

func (*KeyLog) Append

func (l *KeyLog) Append(keyVersion uint32, tokenKeyID [32]byte, notBefore uint64) uint64

Append vouches for an issuer key (its key version and 32-byte token key id, e.g. tokenprofile Issuer.KeyVersion() and TokenKeyID()). Returns the record's seq.

func (*KeyLog) Head

func (l *KeyLog) Head() [32]byte

Head returns the current chain head.

func (*KeyLog) Records

func (l *KeyLog) Records() []KeyRecord

Records returns the log's records (the caller must not mutate them).

type KeyRecord

type KeyRecord struct {
	// Seq is the record's position in the chain, 0-based.
	Seq uint64 `json:"seq"`
	// KeyVersion is the issuer key_version this record vouches for.
	KeyVersion uint32 `json:"key_version"`
	// TokenKeyID is the hex of the 32-byte issuer key id — the same id
	// pinned into tokens.
	TokenKeyID string `json:"token_key_id"`
	// NotBefore is Unix seconds the key becomes valid (informational).
	NotBefore uint64 `json:"not_before"`
}

KeyRecord is one published issuer key in the log.

type LogSigner

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

LogSigner is the log operator's FAEST-128f signing key. Clients pin Public(). The seed-to-key derivation is Go-specific (SHAKE256 keystream into faest KeyGen; the reference uses a ChaCha20 rng) — keys derived from the same seed differ across the two stacks, but published keys, logs, and signatures are fully wire-compatible.

func NewLogSigner

func NewLogSigner(seed []byte) (*LogSigner, error)

NewLogSigner derives the operator key pair from a 32-byte seed.

func (*LogSigner) Public

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

Public returns the 32-byte log public key (FAEST-128f owf input || owf output, the reference's to_bytes encoding).

func (*LogSigner) Sign

func (s *LogSigner) Sign(log *KeyLog, rho []byte) SignedHead

Sign commits to the log's current head. rho is the FAEST signer randomness (LambdaBytes; nil selects deterministic signing).

type SignedHead

type SignedHead struct {
	// Seq is the index of the last record covered (records count - 1).
	Seq uint64 `json:"seq"`
	// Head is the chain head hash, hex.
	Head string `json:"head"`
	// Sig is the FAEST-128f signature over sthDomain||seq_be||head,
	// standard base64.
	Sig string `json:"sig"`
}

SignedHead is the operator's FAEST-128f commitment to the chain head.

Jump to

Keyboard shortcuts

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