TSP SDK Technical specification

This document tries to focus on aspects that pertain to the SDK; i.e. how the TSP Specification impacts the design choices for the Rust SDK. Since the TSP Specification is still in the process of being finalized, however, there may be some duplication.

Protocol overview

At its core, TSP consists of "simply sending a message" between parties; except that this message is (often) encrypted and (always) signed. In this way the parties have confidence that any messages received are always by the same entity, and trust can be built.

TSP uses Verified Identifiers to designate the sender and receiver of messages. A mechanism out of scope for this project (but that we will have to write some simple examples of) will allow applications to retrieve addresses and public keys for a VID.

A TSP message therefore contains at least the following information:

  • Who is the originating sender?
  • Who is the intended receiver?
  • A message payload (encrypted or unencrypted), which can either be 'simple content' or a Control Message.
  • A signature

So, a confidential message will conceptually look like this:

Ciphertext Authenticated data Non-confidential data Sender VID Receiver VID Envelope Signature

And a non-confidential message, when there is no receiver VID, will look like this:

Authenticated data Non-confidential data Sender VID Envelope Signature

Modes of operation

  1. Direct mode: TSP messages can be exchanged directly between two parties via publicly known VID's ("Well-Known VID's"); that gives confidentiality and authenticity but not much privacy.

  2. Nested mode: TSP messages can be exchanged as the 'payload' of another TSP message using not-publicly known VID's. Such a nested connection is established via TSP Control Messages. This gives a little bit more privacy.

  3. Routed mode: TSP messages can be routed through intermediaries to further hide the fact that two parties are communicating. This is done by parties first establishing "nested" communication lines between every involved party and then sending a message that spans over those nested communications lines.

High-level architecture

The SDK will consist of functions that can be called by an application to completely perform all TSP-specific operations, such as:

  • Generating/retrieving/storing VID's
  • Control operations on a private key associated with a VID
  • Obtaining transport layer address information and other metadata from a verified VID.
  • Creation and processing of TSP messages

This allows applications the flexibility to incorporate TSP in an existing setup: i.e., an application can create a TSP message but chose by itself how and when to send it.

For other use cases, the SDK will also contain some convenience functions such as "generate-and-send" for some common transport layers (such as HTTPS or QUIC) for applications that don't need this flexibility.

SDK General Requirements

Cryptography

_DescriptionRationaleConsequence
C1Encryption primitives chosen have to be IND-CCA2 secureThis is the strongest notion of security: under an adaptive chosen ciphertext attack, the attacker cannot recognize correct ciphertext.We use HPKE-Auth for encryption, a modern asymmetric "weakly authenticated" encryption standard
C2Signature schemes have to be SUF-CMA secureThis is the strongest notion of unforgeability, meaning an attacker cannot create valid signatures themselves even if given a "signing oracle".Ed25519 will be used for creating non-repudiation signatures in TSP messages.
C3Cryptographic code has to be reliableTSP relies heavily on cryptography being reliable, and we should not write these ourselves.For crypto "back-ends", code will come from the RustCrypto and DALEK projects. We avoid ring due to maintenance issues and libsodium since its Rust binding has been deprecated by its maintainer.
C4TSP must be resilient against key compromise eventsIf a private key is leaked, the goal of TSP is compromisedThe SDK will not have an API for providing the private key of a VID to an application. Furthermore, HPKE is used that offers more protection against KCI.

Interoperability

_DescriptionRationaleConsequence
I1The implementation must only use third-party dependencies that are "well adopted" by the Rust community and actively maintained.This will "future-proof" the SDK by reduce the chance that the SDK will rely on code that will be abandoned, or that it will be unpopular by requiring uncommon dependencies.Before taking a dependency, we check its activity status and number of downloads. In particular, we will have to write our own CESR support libraries.
I2TSP messages must support CESR encodingCESR encoding is important for credibility in the wider Trust-over-IP community and interoperability with KERITSP messages will be formatted using CESR
I3TSP messages must be capable of being easily generated and parsed in wide variety of contextsTSP must be a general protocolTSP will use CESR in the "B" domain as the canonical representation that will be signed, since that reduces the impact of the choice for CESR.
I4The TSP SDK must be usable by programs not written in RustRust is a secure language, but not a "lingua franca"Bindings will be written to make the SDK usable from C, Python and JavaScript.
I5The SDK must not impose unduly restrictive limitations of useThis allows for easier adoption by existing applicationsTSP message creation/processing and sending/receiving will be split up in different functions.

TSP Specification Conformance

_DescriptionRationaleConsequence
S1TSP can be run over many different transport protocolTSP must be a flexible protocolCode will be designed so it is not tightly tied to a single transport layer.
S2The SDK will support "direct mode", "nested mode" and "routed mode"This is essential for achieving TSP's aimsSome design discussion around control messages setting up routed mode will be needed in the future.

Verified Identifiers

_DescriptionRationaleConsequence
V1VID can contain no identifying information, with the exception of "Well Known VIDs"Non-correlation of VID's is required by the TSP specCryptographic means and entropy means must be used for creating unpredictable "inner VIDs"
V2VID is a probabilistically unique identifierThere must be an extremely low change of two VID's being the same; but this chance cannot be made 0An "inner VIDs" must represent at least 128 bits of entropy
V3The specific style of VID is out of scopeThis is part of the TSP "support system"We need to model an interface for VID's at a sufficiently usable and abstract level; and pick a sufficiently general type of VID for the demo application.
V4A verified VID can be resolved to a pair of public encryption and public verification keysVIDs are used instead of public keys in TSPIn the SDK, a known VID has been resolved to a pair of public keys
V5A verified VID can be resolved to a "transport layer address"TSP is a communication protocolIn the SDK, a known VID has been resolved to a form of resource locator such as an e-mail address or URI.
V6A verified VID may also provide additional information about the entity it identifiesThis is what identifiers are typically used for (see DID and X509)The VID interface must support this
V7The information about resolved VID's in the TSP SDK must be treated as confidential and securely storedThis "routing information" links VIDs to addresses and public keys and can compromise the non-correlation requirement for VID'sThis information will be stored in a secure manner (such as in a secure wallet)
V8TSP messages may also be "broadcast", without a designated receivedThis is under consideration in the TSP specificationOur SDK will support the creation of TSP broadcast messages.

Demo

_DescriptionRationaleConsequence
D1The demo must be a good example of how to use the SDKTSP is easier to adopt if developers can 'copy code'The "trust application" side of the demo must not be fairly simple.
D2The demo must be able to demonstrate the particular features of TSPThis will make it easier to understand what TSP achievesThe demo must involve the three pillars of TSP: confidentiality, authenticity, and privacy.

Security properties

The goal of TSP is to provide security guarantees for

  • Authenticity
  • Confidentiality
  • Privacy

of communication between two parties.

Privacy in communication can be optionally enabled by using the "Routed" mode of the TSP protocol.

To get a high degree of confidence, a modern and well-analyzed cryptographic standard for signcryption is chosen. In signcryption asymmetric cryptography is used to encrypt and sign the contents of a message.

Hybrid Public Key Encryption (HPKE, RFC 9180) is a robust method of signcryption using modern cryptographic primitives 1. It combined a "Key encapsulation Mechanism", with a "Key Derivation Function" and primitive for "Authenticated encryption with associated data" to combine asymmetric with symmetric cryptography, to obtain certain security and performance characteristics. HPKE offers the highest notion of confidentiality, namely IN-CCA2.

HPKE offers the possibility to create authenticated plaintext and authenticated ciphertext in one signcryption operation. In TSP a header (containing the sender and receiver VID's) must be authenticated but not encrypted.

Although HPKE offers authentication and confidentiality between two parties, there are two characteristics that are not desirable for TSP:

  • HPKE is vulnerable to key compromise impersonation (KCI). Which means that if Bob's private key is leaked to Eve, Eve can impersonate Alice toward bob.
  • Although two parties communicating can verify the authenticity of messages, an outsider cannot verify that, for instance, the sender as specified in the header of the message really sends the message. Thereby a receiver can also not prove a message was sent by a particular sender to them. This is called receiver unforgeability (RUF).

The overcome to above, an additional signature is created over both the header and the (HPKE) ciphertext of a TSP message. Since both the sender and receiver's VID are present in the header of a message, one can always verify the message was created by the specified sender and that it was intended for the specified receiver. This is a method first proposed in 2.

The additional "outer" signature over the message header (or envelope) plus the ciphertext makes TSP secure against KCI and RUF secure.

A modern and secure public-key signature scheme is used to construct the "outer" signature, namely Ed25519 3, based in the same elliptic-curve cryptography as HPKE. Ed25519 satisfies properties such as EUF-CMA or SUF-CMA (existentially unforgeable under chosen message attacks, strong unforgeability).

Non goals

Hiding plaintext length

By default, TSP does not hide the length of plaintext messages. If the size of the plaintext is confidential, the application layer could take measures to hide the length by, for instance, always sending fixed size messages.

Bidirectional mode

TSP messages are unidirectional. There is no default way of "responding" to a TSP message, other than constructing a new unidirectional message.

Cryptographic primitives

The following underlying cryptographic primitives are chosen for the TSP.

Key Encapsulation Method: DHKEM(X25519, HKDF-SHA256)

Key Derivation Function: HKDF-SHA256

Authenticated Encryption with Associated Data (AEAD) Function: ChaCha20Poly1305

Signature scheme: Ed25519 SHA512

HPKE operation mode: Auth

Encoding

By default, TSP messages are encoded using CESR 4 with a specific extension for TSP 5.

The methods the seal (encrypt, sign) and open (decrypt, verify) a message also encode and decode the message using CESR in the binary domain.

Using a deterministic and predictable binary encoding helps to reliably sign and verify a TSP message.

HPKE usage

The notation below is based on RFC 9180 6.

We create the message header:

Envelope = ConcatCESR(
    [VID sender, VID receiver, Additional header data]
)

We perform a HPKE Seal operation using the single-shot API in Auth mode:

Ciphertext = SealAuth(
    skS = Sender private key,
    pkR = Receiver public key,
    aad = Envelope,
    pt = Message plaintext
)

We sign the header information together with the ciphertext and encapsulated key:

Signature = Sign(
    skS = Sender private key,
    msg = Concat<CESR>(Envelope, Ciphertext),
)

We construct the final message:

Ciphertext Message = ConcatCESR(
    [Envelope, Ciphertext, Signature]
)

The receiver performs verification and decryption as follows.

Parse the CESR encoded message:

[Envelope, Ciphertext, Signature] = SplitCESR(Ciphertext Message)

[VID sender, VID receiver, Additional header data] = SplitCESR(Envelope)

Verify the outer signature:

Verify(
    pkS = Sender public key,
    msg = ConcatCESR(Envelope, Ciphertext)
)

We perform a HPKE Open operation using the single-shot API in Auth mode:

Message plaintext = OpenAuth(
    pkS = Sender public key,
    skR = Receiver private key,
    aad = Envelope,
    ct = Ciphertext
)

Streaming mode

HPKE allows sealing a stream of messages efficiently by only using symmetric cryptography for subsequent messages. We could extend TSP to allow such a streaming mode by setting up a sender and a receiver context. This context holds the key material for the current stream or "session", as described in session 5.1 of RFC 9180. When using a streaming mode in TSP, only the first message contains the full header and the outer signature.

Note that KCI is not a problem for this mode, since the first message still contains the outer signature (created using the senders’ private key). However, naively implementing a streaming mode using HPKE breaks RUF for subsequent messages. One could include a hash of the next message in each streaming message, and thereby securely links each message back to the initial, signed TSP message. In that case RUF still holds.

References


  1. Richard Barnes and Karthikeyan Bhargavan and Benjamin Lipp and Christopher A. Wood, 2022, "Hybrid Public Key Encryption", https://www.rfc-editor.org/info/rfc9180

  2. Jee Hea An, 2001, "Authenticated Encryption in the Public-Key Setting: Security Notions and Analyses", https://eprint.iacr.org/2001/079

  3. Simon Josefsson and Ilari Liusvaara, 2017, "Edwards-Curve Digital Signature Algorithm ( EdDSA)", https://www.rfc-editor.org/info/rfc8032

  4. Samuel M. Smith, 2021, "Composable Event Streaming Representation ( CESR)", https://datatracker.ietf.org/doc/draft-ssmith-cesr

  5. https://github.com/WebOfTrust/keripy/discussions/612#discussioncomment-7739043

  6. https://www.rfc-editor.org/rfc/rfc9180.html#name-notation