Documentation
¶
Overview ¶
Package tsp implements the Trust Spanning Protocol (TSP), Rev 3 (YTSP-AAC, version 0.2), as specified by the Trust over IP Foundation.
A TSP message is an envelope (version, sender VID, receiver VID), a payload that is either encrypted or carried in the clear, and a signature over both, all framed in binary-domain CESR. This package encodes and decodes every Rev 3 payload type:
- SCS: upper-layer application data (XSCS)
- CTL: generic control data for the layer above TSP (XCTL)
- PAD: padding messages (XPAD)
- RFI, RFA, RFD: the relationship forming protocol (XRFI / XRFA / XRFD), with self-addressing digests (SAIDs), reply paths and referrals
- HOP: nested and routed messages (XHOP)
under four schemes: HPKE-Base (DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, ChaCha20Poly1305), HPKE-Base with the MLKEM768-X25519 hybrid KEM and ML-DSA-65 signatures, the libsodium sealed box, and signed-only.
Stateless API ¶
Pack builds a message, Open verifies and decrypts one, and Peek reads the envelope an intermediary sees:
packed, err := tsp.Pack(alice, bob.Public(), &tsp.SCS{Data: []byte("hi")}, nil)
msg, err := tsp.Open(bob, alice.Public(), packed.Message)
Keys are carried by Identity (public) and PrivateIdentity. Nothing is resolved by Pack or Open; the caller supplies both parties.
Endpoint ¶
Endpoint adds VID resolution (VidResolver), relationship state (Store) and the relationship forming state machine: Invite, Accept, Cancel, Send and Receive. It performs no I/O, so any transport can be layered on top.
Parsing ¶
Parsing is strict and bounded: primitives must be canonically encoded, counts must agree with the bytes they frame, trailing bytes are rejected, and an unknown MAJOR version is refused. Every error is an *Error whose Kind says why (see ErrorKind).
Example ¶
package main
import (
"fmt"
tsp "github.com/affinidi/affinidi-tsp-go"
)
func main() {
alice, _ := tsp.GenerateIdentity("did:example:alice", tsp.SigKeyEd25519, tsp.EncKeyX25519, nil)
bob, _ := tsp.GenerateIdentity("did:example:bob", tsp.SigKeyEd25519, tsp.EncKeyX25519, nil)
packed, err := tsp.Pack(alice, bob.Public(), &tsp.SCS{Data: []byte("hello world")}, nil)
if err != nil {
panic(err)
}
env, _ := tsp.Peek(packed.Message)
fmt.Println(env.Sender, "->", env.Receiver, "confidential:", env.Confidential)
msg, err := tsp.Open(bob, alice.Public(), packed.Message)
if err != nil {
panic(err)
}
fmt.Printf("%s %s\n", msg.Scheme, msg.Payload.(*tsp.SCS).Data)
}
Output: did:example:alice -> did:example:bob confidential: true hpke-base hello world
Index ¶
- Constants
- Variables
- func VerifyReferral(m *Message, introduced *Identity) error
- type CTL
- type Digest
- type DigestAlg
- type EncKeyType
- type Endpoint
- func (e *Endpoint) Accept(ctx context.Context, from, to string) (*Packed, error)
- func (e *Endpoint) AddIdentity(id *PrivateIdentity) error
- func (e *Endpoint) Cancel(ctx context.Context, from, to string) (*Packed, error)
- func (e *Endpoint) Invite(ctx context.Context, from, to string) (*Packed, error)
- func (e *Endpoint) Receive(ctx context.Context, msg []byte) (*Event, error)
- func (e *Endpoint) Send(ctx context.Context, from, to string, data []byte) (*Packed, error)
- func (e *Endpoint) State(ctx context.Context, local, remote string) (Relationship, error)
- type EndpointOption
- type Envelope
- type Error
- type ErrorKind
- type Event
- type EventKind
- type HOP
- type Identity
- type MemoryStore
- type Message
- type PAD
- type PackOptions
- type Packed
- type Payload
- type PayloadType
- type PrivateIdentity
- type RFA
- type RFD
- type RFI
- type Referral
- type Relationship
- type RelationshipState
- type SCS
- type Scheme
- type SenderField
- type SigKeyType
- type StaticResolver
- type Store
- type Version
- type VidResolver
Examples ¶
Constants ¶
const ( // MaxMessageSize bounds the size of a whole encoded message. MaxMessageSize = 64 << 20 // MaxHops bounds a hop list or reply path. MaxHops = 64 )
Limits applied to untrusted input.
const MaxVIDSize = 64 * 1024
MaxVIDSize bounds the length of any VID this package encodes or accepts. It is generous enough for long-form did:peer identifiers carrying post-quantum keys.
const NonceSize = 16
NonceSize is the length of a TSP nonce (128 bits).
Variables ¶
var ( ErrInternal = &Error{Kind: KindInternal} ErrMalformed = &Error{Kind: KindMalformed} ErrVersion = &Error{Kind: KindVersion} ErrSignature = &Error{Kind: KindSignature} ErrDecrypt = &Error{Kind: KindDecrypt} ErrSender = &Error{Kind: KindSender} ErrReceiver = &Error{Kind: KindReceiver} ErrDigest = &Error{Kind: KindDigest} ErrRelationship = &Error{Kind: KindRelationship} ErrUnsupported = &Error{Kind: KindUnsupported} ErrInvalidInput = &Error{Kind: KindInvalidInput} )
Sentinel errors, one per kind, for use with errors.Is.
var CurrentVersion = Version{Major: 0, Minor: 2}
CurrentVersion is the version this package emits: 0.2, encoded YTSP-AAC.
var ErrNotFound = errors.New("tsp: not found")
ErrNotFound is returned by resolvers and stores for an unknown VID or relationship.
Functions ¶
func VerifyReferral ¶
VerifyReferral checks the Signature_new of an invite that introduces a new VID (a Referral), against introduced, the resolved new VID.
Open does not do this: the key of the introduced VID is exactly what the invite exists to convey, so it has to be resolved first. Until a caller verifies it, a referral is only the sender's claim.
Types ¶
type CTL ¶
type CTL struct {
Data []byte
}
CTL is a generic control payload (XCTL) for the layer above TSP. It has the same shape as SCS.
func (*CTL) Type ¶
func (*CTL) Type() PayloadType
type Digest ¶
Digest is a TSP digest: a 256-bit hash and the algorithm that produced it.
func (Digest) Compare ¶
Compare orders digests lexicographically by their binary-domain value, the order the RFI race tie-break uses.
type DigestAlg ¶
type DigestAlg uint8
DigestAlg is the hash function of a TSP digest, identified on the wire by the digest's CESR code.
type EncKeyType ¶
type EncKeyType uint8
EncKeyType is the KEM a VID's encryption key belongs to.
const ( EncKeyUnknown EncKeyType = iota EncKeyX25519 EncKeyMLKEM768X25519 )
Encryption key types.
func (EncKeyType) String ¶
func (t EncKeyType) String() string
type Endpoint ¶
type Endpoint struct {
// contains filtered or unexported fields
}
Endpoint is a TSP endpoint: a set of VIDs it controls, a resolver for the VIDs of others, and a relationship store. It implements the direct relationship forming protocol (RFI / RFA / RFD) and gates application messages on it. It does no I/O: every operation returns or consumes encoded messages, so any transport can be layered on top.
An Endpoint is safe for concurrent use.
Example ¶
package main
import (
"context"
"fmt"
tsp "github.com/affinidi/affinidi-tsp-go"
)
func main() {
ctx := context.Background()
alice, _ := tsp.GenerateIdentity("did:example:alice", tsp.SigKeyEd25519, tsp.EncKeyX25519, nil)
bob, _ := tsp.GenerateIdentity("did:example:bob", tsp.SigKeyEd25519, tsp.EncKeyX25519, nil)
knowsBob, _ := tsp.NewStaticResolver(bob.Public())
knowsAlice, _ := tsp.NewStaticResolver(alice.Public())
a, b := tsp.NewEndpoint(knowsBob), tsp.NewEndpoint(knowsAlice)
_ = a.AddIdentity(alice)
_ = b.AddIdentity(bob)
invite, _ := a.Invite(ctx, alice.VID, bob.VID)
ev, _ := b.Receive(ctx, invite.Message)
fmt.Println(ev.Kind)
accept, _ := b.Accept(ctx, bob.VID, alice.VID)
ev, _ = a.Receive(ctx, accept.Message)
fmt.Println(ev.Kind)
hello, _ := a.Send(ctx, alice.VID, bob.VID, []byte("hi bob"))
ev, _ = b.Receive(ctx, hello.Message)
fmt.Println(ev.Kind, string(ev.Data))
state, _ := b.State(ctx, bob.VID, alice.VID)
fmt.Println(state.State)
}
Output: invite accept message hi bob bidirectional
func NewEndpoint ¶
func NewEndpoint(resolver VidResolver, opts ...EndpointOption) *Endpoint
NewEndpoint creates an endpoint that resolves peers with resolver.
func (*Endpoint) Accept ¶
Accept answers the invite received from remote VID to, from local VID from.
func (*Endpoint) AddIdentity ¶
func (e *Endpoint) AddIdentity(id *PrivateIdentity) error
AddIdentity registers a VID this endpoint controls.
func (*Endpoint) Cancel ¶
Cancel declines a pending invite, withdraws one we sent, or cancels an established relationship, and forgets the relationship locally.
The RFD names the relationship by a digest the remote holds: for an established relationship, the digest this side received (the Reply_Digest for the inviter, the Digest for the accepter); for a pending invite, that invite's Digest.
func (*Endpoint) Invite ¶
Invite sends a relationship forming invite from a local VID to a remote one. It is refused while an invite from the remote is pending (accept it instead) or once the relationship is established. Re-inviting while an invite is outstanding replaces it.
func (*Endpoint) Receive ¶
Receive opens a message addressed to one of this endpoint's VIDs and applies it to the relationship state.
Relationship rules: an invite crossing our own outstanding invite for the same pair is kept only if its digest is lower (binary comparison), otherwise it is refused; an accept must echo the digest of our outstanding invite; a cancel must name a digest of an existing relationship; application data is accepted only over a bidirectional relationship. A refused message is an error of kind KindRelationship and leaves the state unchanged.
type EndpointOption ¶
type EndpointOption func(*Endpoint)
EndpointOption configures an Endpoint.
func WithRand ¶
func WithRand(r io.Reader) EndpointOption
WithRand sets the randomness source (default: crypto/rand).
func WithStore ¶
func WithStore(s Store) EndpointOption
WithStore sets the relationship store (default: a new MemoryStore).
type Envelope ¶
type Envelope struct {
Version Version
Sender, Receiver string
// Confidential reports whether the payload is encrypted.
Confidential bool
// SealedBox reports a sealed-box ciphertext (code C) rather than HPKE
// (code F). Whether an HPKE message uses the post-quantum KEM is not
// visible on the wire.
SealedBox bool
}
Envelope is what Peek reveals without keys: what an intermediary sees.
type Error ¶
Error is the error type returned by this package.
type ErrorKind ¶
type ErrorKind uint8
ErrorKind classifies why an operation failed. Every error returned by this package is an *Error carrying one, so a caller can branch on the kind with errors.Is against the sentinel values below, or with KindOf.
const ( KindInternal ErrorKind = iota // anything else KindMalformed // CESR framing cannot be parsed KindVersion // unknown or unsupported TSP version KindSignature // signature verification failed KindDecrypt // decryption or authentication failed KindSender // envelope/ESSR sender mismatch, wrong sender key, unknown sender KindReceiver // message not addressed to the receiver KindDigest // a SAID does not verify KindRelationship // relationship state forbids the message KindUnsupported // scheme, payload type or option not supported KindInvalidInput // the caller's request is invalid )
Error kinds.
type Event ¶
type Event struct {
Kind EventKind
// From is the remote (envelope sender) VID, To the local VID.
From, To string
// Data is the application data of an EventMessage or EventControl.
Data []byte
// Digest is the invite digest (invite, accept) or the named digest (cancel).
Digest *Digest
// ReplyDigest is the accept's own digest.
ReplyDigest *Digest
// Message is the opened message.
Message *Message
}
Event is the outcome of receiving a message.
type EventKind ¶
type EventKind uint8
EventKind classifies a received message.
const ( EventInvite EventKind = iota + 1 // an RFI EventAccept // an RFA answering our invite EventCancel // an RFD EventMessage // application data (XSCS) EventControl // generic control payload (XCTL) EventPadding // a padding message (XPAD) EventHop // a nested or routed message (XHOP), inner unopened )
Event kinds.
type HOP ¶
HOP carries a complete inner TSP message (XHOP): nested when Hops is empty, routed otherwise.
func (*HOP) Type ¶
func (*HOP) Type() PayloadType
type Identity ¶
type Identity struct {
// VID is the verifiable identifier, e.g. a DID or URN.
VID string
// SigKeyType and SigningKey are the VID's public signature key: 32 bytes
// for Ed25519, 1952 for ML-DSA-65.
SigKeyType SigKeyType
SigningKey []byte
// EncKeyType and EncryptionKey are the VID's public encryption key: 32
// bytes for X25519, 1216 for MLKEM768-X25519. May be empty for a VID that
// only signs.
EncKeyType EncKeyType
EncryptionKey []byte
}
Identity is the public view of a VID: the identifier and the keys bound to it. It is what a VidResolver produces.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore is an in-memory Store.
func NewMemoryStore ¶
func NewMemoryStore() *MemoryStore
NewMemoryStore returns an empty MemoryStore.
func (*MemoryStore) DeleteRelationship ¶
func (s *MemoryStore) DeleteRelationship(_ context.Context, local, remote string) error
DeleteRelationship implements Store.
func (*MemoryStore) Relationship ¶
func (s *MemoryStore) Relationship(_ context.Context, local, remote string) (Relationship, error)
Relationship implements Store.
func (*MemoryStore) SetRelationship ¶
func (s *MemoryStore) SetRelationship(_ context.Context, local, remote string, r Relationship) error
SetRelationship implements Store.
type Message ¶
type Message struct {
Version Version
// Sender and Receiver are the envelope VIDs. Receiver is "" when the
// envelope names the NULL VID.
Sender, Receiver string
// Scheme is how the payload was protected.
Scheme Scheme
// PayloadSender is the ESSR VID_sndr field inside the payload; "" for the
// NULL VID. When present it has been checked against Sender.
PayloadSender string
// Padding is the content of the Padding_Field.
Padding []byte
// Payload is the decoded payload. A *HOP's Inner message is not opened.
Payload Payload
}
Message is an opened TSP message.
func Open ¶
func Open(receiver *PrivateIdentity, sender *Identity, msg []byte) (*Message, error)
Open verifies and decrypts a message addressed to receiver from sender.
It checks, in order: framing; that the envelope names receiver and sender; the signature, under sender's signing key; decryption, with the envelope as HPKE associated data; the payload framing; the ESSR sender field against the envelope; and any SAID the payload carries.
receiver needs its decryption private key unless the message is signed-only.
type PAD ¶
type PAD struct {
// Nonce is 16 bytes. On Pack a nil Nonce is filled from the random source.
Nonce []byte
}
PAD is a padding message (XPAD). Pad the message with PackOptions.Padding.
func (*PAD) Type ¶
func (*PAD) Type() PayloadType
type PackOptions ¶
type PackOptions struct {
// Scheme selects the payload protection. SchemeAuto picks HPKE by the
// receiver's encryption key type.
Scheme Scheme
// Padding is the content of the payload's Padding_Field. The receiver
// discards it; it exists to hide the payload's size.
Padding []byte
// PayloadSender selects the ESSR sender field.
PayloadSender SenderField
// DigestAlg is the algorithm of the SAID an RFI or RFA carries.
// DigestDefault uses Blake2b-256 under the sealed box, SHA2-256 otherwise.
DigestAlg DigestAlg
// ReferralSigner is the introduced VID, used to produce Signature_new when
// an RFI carries a Referral without a Signature.
ReferralSigner *PrivateIdentity
// Rand is the source of nonces, ephemeral keys and signature randomness.
// Defaults to crypto/rand.
Rand io.Reader
// Ephemeral pins the encryption's ephemeral key material, making the
// output reproducible: the HPKE DeriveKeyPair input ikmE under HPKE-Base,
// the ephemeral X25519 secret under the sealed box. It exists to reproduce
// published test vectors. Never set it otherwise: reusing ephemeral key
// material destroys confidentiality. Not supported for HPKE-PQ.
Ephemeral []byte
}
PackOptions tunes Pack. The zero value is valid.
type Packed ¶
type Packed struct {
// Message is the binary-domain (qb2) wire encoding.
Message []byte
// Digest is the SAID the message carries: an RFI's Digest or an RFA's
// Reply_Digest. Nil for other payload types.
Digest *Digest
}
Packed is an encoded TSP message.
func Pack ¶
func Pack(sender *PrivateIdentity, receiver *Identity, payload Payload, opts *PackOptions) (*Packed, error)
Pack encodes, protects and signs a TSP message from sender to receiver.
sender must hold its signing private key. receiver supplies the encryption key for a confidential scheme; it may be nil for a signed-only message, in which case the envelope names the NULL VID as receiver.
type Payload ¶
type Payload interface {
Type() PayloadType
// contains filtered or unexported methods
}
Payload is one of *SCS, *CTL, *PAD, *RFI, *RFA, *RFD or *HOP.
type PayloadType ¶
type PayloadType uint8
PayloadType is a TSP payload type code.
const ( PayloadSCS PayloadType = iota + 1 // XSCS, upper-layer application payload PayloadCTL // XCTL, generic control payload PayloadPAD // XPAD, padding message PayloadRFI // XRFI, relationship forming invite PayloadRFA // XRFA, relationship forming accept PayloadRFD // XRFD, relationship forming decline / cancel PayloadHOP // XHOP, nested or routed message )
Payload types.
func (PayloadType) String ¶
func (t PayloadType) String() string
type PrivateIdentity ¶
type PrivateIdentity struct {
Identity
// SigningPrivateKey is the Ed25519 seed (32 bytes, or 64 bytes seed||pk),
// or the ML-DSA-65 private key as a 32-byte seed or the 4032-byte expanded
// encoding.
SigningPrivateKey []byte
// DecryptionPrivateKey is the raw X25519 private key (32 bytes) or the
// MLKEM768-X25519 private key seed (32 bytes).
DecryptionPrivateKey []byte
}
PrivateIdentity is a VID this endpoint controls: its public Identity plus the private keys. Either private key may be absent when the identity is only used for the operations that need the other.
func GenerateIdentity ¶
func GenerateIdentity(vid string, sigType SigKeyType, encType EncKeyType, rng io.Reader) (*PrivateIdentity, error)
GenerateIdentity creates a fresh PrivateIdentity for vid with the given key types. rng defaults to crypto/rand.
func NewPrivateIdentity ¶
func NewPrivateIdentity(vid string, sigType SigKeyType, signingPrivateKey []byte, encType EncKeyType, decryptionPrivateKey []byte) (*PrivateIdentity, error)
NewPrivateIdentity builds a PrivateIdentity from private keys, deriving the public keys. Either private key may be nil (with its type left unknown).
func (*PrivateIdentity) Public ¶
func (p *PrivateIdentity) Public() *Identity
Public returns the public Identity (a copy).
func (*PrivateIdentity) Validate ¶
func (p *PrivateIdentity) Validate() error
Validate checks the public identity and that each private key present corresponds to its public key.
type RFA ¶
type RFA struct {
// InviteDigest is the Digest of the invite being accepted, echoed verbatim.
InviteDigest Digest
// ReplyDigest is the accept's own SAID. Computed by Pack and verified by
// Open; ignored on input.
ReplyDigest Digest
}
RFA is a relationship forming accept (XRFA).
func (*RFA) Type ¶
func (*RFA) Type() PayloadType
type RFD ¶
type RFD struct {
// Digest names the relationship: the invite's Digest or the accept's
// Reply_Digest. A DigestDefault algorithm on input means SHA2-256.
Digest Digest
}
RFD is a relationship forming decline or cancel (XRFD).
func (*RFD) Type ¶
func (*RFD) Type() PayloadType
type RFI ¶
type RFI struct {
// Nonce is 16 bytes. On Pack a nil Nonce is filled from the random source.
Nonce []byte
// ReplyPath is the route for the accept; empty for a direct reply.
ReplyPath []string
// Referral, when non-nil, introduces a new VID (parallel relationship
// forming).
Referral *Referral
// Digest is the invite's own SAID. Computed by Pack and verified by Open;
// ignored on input.
Digest Digest
}
RFI is a relationship forming invite (XRFI).
func (*RFI) Type ¶
func (*RFI) Type() PayloadType
type Referral ¶
type Referral struct {
VID string
// Signature is a 64-byte Ed25519 or 3309-byte ML-DSA-65 signature. On Pack,
// a nil Signature is produced with PackOptions.ReferralSigner.
Signature []byte
}
Referral is the Referral_Field of an invite: a new VID introduced over an existing relationship, with that VID's own signature over the invite.
type Relationship ¶
type Relationship struct {
State RelationshipState
// Digest is the invite's Digest, which identifies the inviter's direction
// of the relationship (and is the thread identifier).
Digest *Digest
// ReplyDigest is the accept's Reply_Digest, identifying the accepter's
// direction. Set once bidirectional.
ReplyDigest *Digest
// Initiator reports whether the local VID sent the invite.
Initiator bool
}
Relationship is the stored state of <local, remote>.
type RelationshipState ¶
type RelationshipState uint8
RelationshipState is the state of the relationship between a local and a remote VID.
const ( // StateNone: no relationship. StateNone RelationshipState = iota // StateInviteSent: we sent an RFI and await the RFA. StateInviteSent // StateInviteReceived: we received an RFI and have not answered it. StateInviteReceived // StateBidirectional: the RFI/RFA exchange completed. StateBidirectional )
Relationship states.
func (RelationshipState) String ¶
func (s RelationshipState) String() string
type SCS ¶
type SCS struct {
// Data is the application bytes, carried as exactly one CESR Bytes
// primitive inside the -A## stream. Its format is the upper layer's; Open
// rejects a stream holding anything else (spec issue #77).
Data []byte
}
SCS is an upper-layer application payload (XSCS).
func (*SCS) Type ¶
func (*SCS) Type() PayloadType
type Scheme ¶
type Scheme uint8
Scheme is how a message's payload is protected.
const ( // SchemeAuto selects HPKE by the receiver's encryption key type: HPKE-Base // for X25519, HPKE-PQ for MLKEM768-X25519. Only meaningful for Pack. SchemeAuto Scheme = iota // SchemeHPKEBase is HPKE-Base with DHKEM(X25519, HKDF-SHA256), HKDF-SHA256 // and ChaCha20Poly1305 (ciphertext code F). SchemeHPKEBase // SchemeHPKEPQ is HPKE-Base with the MLKEM768-X25519 hybrid KEM (ciphertext // code F; distinguished only by the receiver's key type). SchemeHPKEPQ // SchemeSealedBox is the libsodium anonymous sealed box (ciphertext code C). SchemeSealedBox // SchemeSignedOnly carries the payload in the clear, signed. SchemeSignedOnly )
Schemes.
func (Scheme) Confidential ¶
Confidential reports whether the scheme encrypts the payload.
type SenderField ¶
type SenderField uint8
SenderField selects what a payload carries in its ESSR VID_sndr field.
const ( // SenderFieldDefault is the scheme's default: the sender's VID under the // sealed box (which requires it), the NULL VID otherwise. SenderFieldDefault SenderField = iota // SenderFieldNull carries the NULL VID 4BAA. Not permitted under the sealed // box. SenderFieldNull // SenderFieldPresent carries the envelope sender's VID. SenderFieldPresent )
ESSR sender field choices.
type SigKeyType ¶
type SigKeyType uint8
SigKeyType is the signature scheme a VID's signing key belongs to.
const ( SigKeyUnknown SigKeyType = iota SigKeyEd25519 SigKeyMLDSA65 )
Signature key types.
func (SigKeyType) String ¶
func (t SigKeyType) String() string
type StaticResolver ¶
type StaticResolver struct {
// contains filtered or unexported fields
}
StaticResolver resolves VIDs from an in-memory table. It suits tests, out-of-band introductions and self-certifying VIDs whose keys are known.
func NewStaticResolver ¶
func NewStaticResolver(ids ...*Identity) (*StaticResolver, error)
NewStaticResolver returns a resolver holding the given identities.
func (*StaticResolver) Add ¶
func (r *StaticResolver) Add(id *Identity) error
Add registers (or replaces) an identity.
type Store ¶
type Store interface {
// Relationship returns the relationship, or a zero Relationship (StateNone)
// if there is none.
Relationship(ctx context.Context, local, remote string) (Relationship, error)
// SetRelationship stores the relationship.
SetRelationship(ctx context.Context, local, remote string, r Relationship) error
// DeleteRelationship removes the relationship if it exists.
DeleteRelationship(ctx context.Context, local, remote string) error
}
Store persists relationships. Implementations must be safe for concurrent use; the Endpoint serialises its own read-modify-write sequences.
type Version ¶
type Version struct {
Major, Minor int
}
Version is a TSP protocol version, MAJOR.MINOR.
type VidResolver ¶
VidResolver resolves a VID to its current public Identity. Implementations perform whatever verification the VID type requires (DID resolution, KERI key state, ...). A resolver must be safe for concurrent use.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cesr implements the binary-domain (qb2) CESR primitives that the Trust Spanning Protocol uses to frame its messages.
|
Package cesr implements the binary-domain (qb2) CESR primitives that the Trust Spanning Protocol uses to frame its messages. |
|
Package crypto holds the cryptographic primitives TSP Rev 3 composes: HPKE-Base over DHKEM(X25519, HKDF-SHA256) with ChaCha20Poly1305, the same suite over the MLKEM768-X25519 hybrid KEM, the libsodium anonymous sealed box, Ed25519 and ML-DSA-65 signatures, and the SHA2-256 / Blake2b-256 digests.
|
Package crypto holds the cryptographic primitives TSP Rev 3 composes: HPKE-Base over DHKEM(X25519, HKDF-SHA256) with ChaCha20Poly1305, the same suite over the MLKEM768-X25519 hybrid KEM, the libsodium anonymous sealed box, Ed25519 and ML-DSA-65 signatures, and the SHA2-256 / Blake2b-256 digests. |