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 ¶
- Variables
- func HeadOf(records []KeyRecord) ([32]byte, error)
- func VerifyConsistency(old SignedHead, newRecords []KeyRecord) error
- func VerifyInclusion(records []KeyRecord, tokenKeyID [32]byte) (uint64, error)
- func VerifyLog(logPub [32]byte, records []KeyRecord, sth SignedHead) error
- type KeyLog
- type KeyRecord
- type LogSigner
- type SignedHead
Constants ¶
This section is empty.
Variables ¶
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 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 ¶
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.
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 ¶
NewLogSigner derives the operator key pair from a 32-byte seed.
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.