Antheos Security Layer

This specification is a draft. It may change in ways that break compatibility, and no implementation of it is published at present.

ANTHEOS_SECURITY_LAYER_SPEC.md (Markdown, 32,128 bytes)

Version 0.4 — Level 2 Specification - Security

© Are Bjørby are.bjorby@langsyn.org November 2026

This is a draft. Its handshakes are the Noise Protocol Framework's. The way its records use them, and the way they fit Level 1, are this document's own, and no cryptographer has reviewed them. It has been exercised in a model and on no bus.


Contents

  1. Introduction
  2. Design Principles
  3. Terms and Definitions
  4. Construction
  5. Keys
  6. Records
  7. Handshake
  8. Transport
  9. Level 1 Behaviour
  10. Replacing the Layer
  11. Conformance
  12. Cost
  13. Security Considerations
  14. Licensing

1. Introduction

Antheos Level 1 carries what it is given and protects none of it. It has no encryption, no authentication and no integrity (Level 1 Section 15).

This document defines the Antheos Security Layer, a Level 2 protocol carried inside Level 1 messages. It seals what it carries, so that only the two ends of a session can read or change it, and it lets each end authenticate the other by a key. Neither end has to reveal its OID, DID or IID to run it.

"Level 1" means the Antheos Protocol, Version 1.9, Level 1 Specification - Transport. "Level 1 Section 11.1.2" refers to that document, and "Section 6" to this one.

The layer knows Level 1 and nothing above itself. What it carries is content: bytes it does not read. It is a foundation for higher-level protocols.

The layer needs no change to Level 1: no new symbol, word or verb. Level 1 does not require it and does not know of it. A device's designer may use this layer, replace it with another (Section 10), or use none.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 (RFC 2119, RFC 8174) when, and only when, they appear in all capitals, as shown here.


2. Design Principles


3. Terms and Definitions

Term Definition
Layer This protocol, or one end's running of it for one session
Content The bytes the layer carries for the level above. The layer does not read them
Record What the layer sends: the one tail block of one Call or Notify (Section 6)
Handshake The three messages that agree the session's keys (Section 7)
Initiator The instance that sends message 1. It stays the initiator whatever a Resume does to Level 1's opener
Responder The other end of the handshake
Static key The X25519 key pair an end authenticates with, kept as long as its designer chooses (Section 5)
Ephemeral key The X25519 key pair an end makes for one handshake and then discards
Sealed Encrypted and authenticated with ChaCha20-Poly1305
Counter A transport record's own number within its direction (Section 6.3)
Mark The highest counter a receiver has accepted, kept for Calls and for Notifies apart (Section 8.2)

4. Construction

4.1 Noise

The layer uses the Noise Protocol Framework, revision 34, with one cipher suite: X25519, ChaCha20-Poly1305 and SHA-256. It uses two handshake patterns.

Protocol name Pattern Use
Noise_XX_25519_ChaChaPoly_SHA256 -> e <- e, ee, s, es -> s, se First contact: neither end holds the other's key
Noise_XK_25519_ChaChaPoly_SHA256 <- s ... -> e, es <- e, ee -> s, se The initiator already holds the responder's public key

Each protocol name is exactly 32 bytes long. Noise uses a name of at most 32 bytes as its initial hash as it stands, so neither name is hashed. An implementation that hashes it agrees with itself and with nothing else.

The prologue of both is the ASCII bytes of antheos-secure-1. A later version of this layer takes another name, so that two versions fail at their first sealed message and nothing is negotiated between them.

4.2 What Each Handshake Shows

Observer XX XK
A listener Neither end's static key Neither end's static key
A stranger who opens a handshake The responder's static key Nothing, if it does not already hold that key. The key is never sent, and the stranger's message 1 draws no answer
The responder The initiator's static key, once the initiator has accepted the responder's The same

Under XK, a recorded message 1 replayed to a device on another bus shows whether that device holds the key the message was made for. Under XX alone, a responder would have to choose between being recognised and being anonymous, and XK is the handshake that lets it be both.

4.3 Choices Noise Leaves Open

An end MUST draw its ephemeral keys from a cryptographically secure source. Level 1's device entropy is not such a source unless its designer has made it one. A device with none does not run the layer.

An X25519 output of all zeros ends the handshake (Section 7.3).


5. Keys

5.1 A Key Is a Name

An end's static key is an X25519 key pair of its designer's choosing. A key used on two bus connections links them, for anyone who receives it. How long a key lives is the device's designer's to decide:

A key that lives for Gives
One session Nothing links sessions. It authenticates nothing: an active attacker can sit in the middle, unnoticed
One bus connection Nothing links buses or connections. A peer can recognise it within that connection only
One peer That peer can recognise the device, and nothing links it to its other peers
The device's life Anyone who receives it can recognise the device, anywhere

A responder under XX chooses its key before it knows who is asking, so it can keep a key per peer only under XK, where the initiator's message 1 names the key it is for. An initiator chooses after message 2.

A static key MUST NOT be derived from an OID, DID or IID.

5.2 Accepting a Key

The layer hands the other end's static key to the device's designer's code, which accepts it or refuses it. Whether by a pinned list, a signature, a key remembered from first contact or anything else is the designer's.

The initiator decides after message 2, before it sends message 3. If it refuses, it sends no message 3 (Section 7.3), so that its own key goes only to an end it has accepted. The responder decides after message 3.

5.3 Holding Keys

The transport keys and counters of a session MUST live in volatile memory only, and die with the session and at a reset. A key that outlived its counter would seal under a nonce already used, which destroys ChaCha20-Poly1305.


6. Records

6.1 Carriage

In a session that runs the layer, every Call and every Notify carries exactly one record, as the block of one BLOB word (Level 1 Section 7.3), and no other payload word. It MUST name its target, since a session message with none is taken by every listener on the bus (Level 1 Sections 11 and 11.1.1). It carries no trace identifier, which would stay in clear (Level 1 Section 11.3).

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]D[SOB]3[EOW] [SOW]*[SOR]D[SOU]B[SOB]32[EOW] [EOM] <32 bytes>
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→7M►↕@♦U→4T►↕@♦D→3►↕*♦D•B→32►♥

A Call from 7M to 4T in session A7K2MQ, at MID 3, with a record of 32 bytes in its tail.

Status, Locate, Resume, Finish, Exception and Scaleback carry no record and stay in clear.

6.2 Kinds

A record's first byte is its kind.

Kind Record Verb
1, 2, 3 XX handshake messages 1, 2, 3 Call
4, 5, 6 XK handshake messages 1, 2, 3 Call
7 Request Call
8 Answer Call
9 Event Notify

A record of any other kind is refused.

6.3 Handshake and Transport Records

handshake record = kind (1 byte) | Noise message
transport record = kind (1 byte) | counter (4 bytes, big-endian) | sealed content | tag (16 bytes)

A transport record is 21 bytes longer than its content. Noise limits a sealed message to 65535 bytes, so content is at most 65519 bytes and a record at most 65540.

The counter runs from 1 to 4294967295 in each direction. It is the record's Noise nonce, set with SetNonce. Noise's Split gives the first key to the initiator's direction and the second to the responder's.

The associated data of a transport record is:

Kind Associated data
Request, Event The kind, as 1 byte
Answer The kind, as 1 byte, then the counter of the request it answers, as 4 bytes, big-endian. Counter 0 stands for handshake message 3

No SID, BID or MID enters a record. A record therefore survives a Resume, which changes a BID, and a gateway, which changes all three (Section 9).


7. Handshake

7.1 Whether a Session Runs the Layer

That is fixed before a session's first Call, by what the two devices were built to do or by the capability an Accept took (Level 1 Section 10.3). It is never negotiated within the session, so nothing inside the layer can be downgraded.

The layer's capability is antheos-secure-1. A Query or Offer for it is in clear, like any other. A direct open (Level 1 Section 11.1.1) needs no Query, and shows no capability.

A device that requires the layer takes no plain session: a Call or Notify with no record is refused (Section 8.3).

7.2 Messages

Message Level 1 From XX tokens XX bytes XK tokens XK bytes
1 The opening Call, MID 1 Initiator e 32 e, es 48
2 The next Call Responder e, ee, s, es 96 e, ee 48
3 A Call Initiator s, se 64 s, se 64

The bytes are the Noise message with no payload, before the kind.

The answer to message 3 is a transport record of kind Answer, bound to counter 0, and is the responder's first. It proves to the initiator that the responder finished. The initiator sends nothing else in the session until it arrives.

Payloads: message 1 carries none, and one that does is refused: under XX it would be in clear, and under XK it could be replayed. Message 2 MAY carry the designer's bytes, a credential for example, which reach whoever sent message 1. Message 3 MAY carry the first content, which reaches an end the initiator has accepted, and the responder's first record answers it.

Computed once: an end writes each handshake message once. Level 1 repeats those bytes if they are lost, and the ephemeral key is not made again.

7.3 Failure


8. Transport

8.1 Sending

Each direction has one counter, and each record takes the next.

The layer seals once. Level 1 repeats the sealed bytes (Level 1 Section 11.1.2). The layer MUST NOT seal a record again for a retransmission, since one counter over two different plaintexts destroys ChaCha20-Poly1305. New content is a new record with a new counter.

A session whose counter would pass 4294967295 ends, and its ends open a new one.

8.2 Receiving

For a Call or Notify from the session's other end that Level 1 would act on:

  1. It carries one BLOB block and no other payload word, or it is refused.
  2. Its kind is Request or Answer on a Call and Event on a Notify, or it is refused.
  3. Its counter is above the mark for its verb, or it is refused. A counter of 0 is refused.
  4. If it is an Answer, a request's answer is due, or it is refused.
  5. Its tag verifies under the counter and the associated data of Section 6.3, or it is refused.
  6. The mark for its verb moves to its counter, and its content goes to the level above.

A receiver keeps two marks, one for Calls and one for Notifies. Level 1 accepts a lost request sent again below a MID already passed (Level 1 Section 11.1.2), and either end may send a Notify while a request is unanswered. One mark would refuse that request every time it came, and it could never arrive. The sender's one counter keeps every nonce distinct.

8.3 Refusal

A message whose record is refused moves no Level 1 state. No MID is noted, and no request counts as answered. To the instance it is a frame that was lost, which Level 1 already allows for, so nothing on the wire changes. A refused record draws no answer.

Level 1 recognises a retransmission first: a request at the MID of the last one answered is answered again from the stored bytes and does not reach the layer.

Level 1 has no checksum, so a corrupted frame reaches the layer. By this rule it costs a retransmission and not a new handshake.

8.4 Requests and Answers

Level 1 ties an answer to its request by order alone: the other end's next Call answers a Call (Level 1 Section 11.1.2). An answer held back until a later request would read as that request's. The associated data of an Answer therefore holds the counter of the request it answers, and it costs nothing on the wire. An end expects the answer to its most recent request, so the answer to one it has abandoned is refused.


9. Level 1 Behaviour

Loss: A record may be lost, as a frame may. A gap in the counters is not an error.

MID wrap: An end MUST open a new session before its MID would wrap. A wrap message has no payload and cannot be authenticated (Level 1 Section 11.1.2), and none is sent in a session that runs the layer, so one that arrives is dropped.

Resume: A Resume moves a session at Level 1 to a new BID and proves nothing (Level 1 Section 11.7). The keys hold the session and not the BID: content from the new BID is accepted if and only if its record is. The handshake's roles do not move. An end that has lost its keys does not Resume, and opens a new session.

Reset: An end that resets has lost its keys (Section 5.3). A peer's next Call to it draws SESSION_NOT_FOUND, and the initiator opens a new session under a fresh SID (Level 1 Section 11.1.1).

Scaleback: A limit a record cannot fit ends the session. There is no plaintext fallback. A forged Scaleback can therefore stop a session and can expose nothing. A device needs to take a tail of 97 bytes under XX and 65 under XK, and 21 bytes more than the content after that.

Tail size: An end running the layer reads no tail longer than 65540 bytes, or a smaller limit of its designer's, and breaks the frame on a longer one (Level 1 Section 7.4).

Gateway: A service on another bus is reached through an instance on both, with a session on each (Level 1 Section 9.3). Such an instance MAY forward records from one session to the other as they stand, verb and tail alike. It needs no key and reads no content. It can sit in the middle of a handshake whose ends accept any key (Section 5.1).


10. Replacing the Layer

A device's designer MAY use another layer, proprietary or not, in place of this one. Another layer takes another capability name, and shares nothing with this one. Nothing in Level 1 favours this layer. A device with a different layer, or with none, is a conforming Level 1 device. Two devices with different layers do not interoperate at this level.


11. Conformance

An end that runs this layer MUST:


12. Cost

This section is non-normative.

The whole frames through the first answer, in bytes, with a 6-character SID, 2-character BIDs, the target named and no content:

Handshake Message 1 Message 2 Message 3 First answer Total
XX 85 149 117 73 424
XK 101 101 117 73 392

On a bus carrying about 1.4 kB/s, either takes about 0.3 s on the wire, before any computing and host latency.

Each end computes four X25519 operations. How long that takes depends on the device, and has been measured on none. Level 1's retransmission timeout and idle time are the designer's (Level 1 Sections 11.3 and 11.1.3), and have to allow for it.


13. Security Considerations

What the layer protects: The content of a session, against reading and change, by anyone but its two ends. A record cannot be replayed, or relabelled as another kind, or delivered as the answer to another request. A session's keys come from fresh ephemeral keys, so recording a session and later taking a static key does not open it.

What it authenticates: A key and nothing more. What a key means is the designer's (Section 5.2). A handshake whose ends accept any key protects against a listener and not against an attacker in the middle.

What stays visible: The SID, the BIDs, the MID, every message's size and timing, that a session runs the layer, and any capability a Query or Offer names. The layer does not hide who is talking to whom on a bus. A level above that needs to hide sizes pads its own content.

A Resume links BIDs: Its SID is in clear, so any listener can tie the new BID to the old one. A device that wants its BIDs unlinked opens a new session instead. Such a device also draws fresh device entropy for every SID, which Level 1 allows (Level 1 Section 11.2), since the SID hash is not cryptographic.

What stays forgeable: Finish, Status, Exception, Scaleback, Locate, Resume, Establish, Conflict, Query, Offer and Accept (Level 1 Section 15). A forger can stop a session or force a new handshake, and can read or change no content. The layer offers no availability.

What goes undetected: The loss of a session's last message. There is no sealed close, and a level above that needs one puts it in its content.

What it costs a device: Forged first messages make a responder compute. Refusing one takes 1 X25519 operation under XK. Answering one takes 3 under XX. Limiting them is the designer's.

Rekeying: There is none within a session. Forward secrecy is per session, and a device that wants it more often opens a new session.

Post-quantum: The layer is not post-quantum secure. Traffic recorded now could be opened by a future quantum computer. A post-quantum key exchange adds kilobytes to a handshake, which is more than the smallest devices this layer serves can carry, and is left to a later name.

Identity: No record names a device. A device that wants to disclose an OID, DID, IID or anything else sends it as content, which then reaches the authenticated peer alone. Whether it does is its designer's (Level 1 Section 5.3).


14. Licensing

MIT License

Copyright (c) 2026 Are Bjørby are.bjorby@langsyn.org

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification and associated documentation files (the "Specification"), to deal in the Specification without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification.

THE SPECIFICATION IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SPECIFICATION OR THE USE OR OTHER DEALINGS IN THE SPECIFICATION.


Appendix A: Worked Example

This appendix is non-normative. Its keys are for this example and for nothing else.

Each key below is a private key, followed by its public key. The SID is A7K2MQ, the initiator's BID is 7M and the responder's 4T.

Key Private Public
Initiator static 3c2aa06d53054abdbe4f257cb729410f00fcaf7c3dc539d933e2775fb6d746b6 35d5320657485768e18cee2f5addb967011a8c1c84ec0e29811cecb625b71717
Responder static a8f052b7e24c27c15212d12b4ad40a2af4e1da69fad13d41815894b680a00d36 fd7b3b2a21b1ebe9e02d7b97833938897ad0d859974c565606d4144ee6ce5b70
Initiator ephemeral, XX 8254c70c60c9a9e453c46900993d69d533797406949d1f14e32b3ab3fd1620c7 25c6396b5cdbabbd53a0221b1507f2cee9bcb36c203b35131609e75a0cffac63
Responder ephemeral, XX fe0e92cc2e799be923f61cc546cfd620a92d5abea070a8c1787558dcfdf8ec32 a7bef60d210cda21357abf0e06d8e0f160c2ef2310b822942885ad0f320c3777
Initiator ephemeral, XK ca6945c76b0e90ee7e2e1fe7bf1ba6f6bc23beb51c3866a4bbb2700de88104b4 5ac670db24b842b088a0fb9f2cfb5512e50b5963cc2108359f6e74e400ef1649
Responder ephemeral, XK 452a815e69b2cbff9c12c38bd68c517e8ccbbc8d5f6857809f34abc2e6116fcc 915aa9cef82c558965fbc39fd77a0f5eb83f3c692a0a5ffc0b519022a838f45d

A.1 XX

Message 1:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]D[SOB]1[EOW] [SOW]*[SOR]D[SOU]B[SOB]33[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→7M►↕@♦U→4T►↕@♦D→1►↕*♦D•B→33►♥
Tail:    0125c6396b5cdbabbd53a0221b1507f2cee9bcb36c203b35131609e75a0cffac
         63

Message 2:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]D[SOB]1[EOW] [SOW]*[SOR]D[SOU]B[SOB]97[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→4T►↕@♦U→7M►↕@♦D→1►↕*♦D•B→97►♥
Tail:    02a7bef60d210cda21357abf0e06d8e0f160c2ef2310b822942885ad0f320c37
         771e793afde2a60fcffda497c3dee72f9dd21ce2c6ed495ca71207628a2094c7
         0a009c6160c40174be0dbaec0e9eaa18ca9050b244dee19596d6c89a62ea810d
         80

Message 3:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]D[SOB]2[EOW] [SOW]*[SOR]D[SOU]B[SOB]65[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→7M►↕@♦U→4T►↕@♦D→2►↕*♦D•B→65►♥
Tail:    03c95e17eb7fe7f2f272b1018301cbd3ae1f3d8d0cf5840ff2321776835f61cc
         d68899d0bd9cd87fab0f9491be09d330b730e6c6df7fcd62e5888b145c42a96f
         e4

The answer to message 3, with counter 1 and empty content:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]D[SOB]2[EOW] [SOW]*[SOR]D[SOU]B[SOB]21[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→4T►↕@♦U→7M►↕@♦D→2►↕*♦D•B→21►♥
Tail:    0800000001431e68b9e8a10a0c816248b42e92594d

A request, counter 1, with the content get_reading:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]D[SOB]3[EOW] [SOW]*[SOR]D[SOU]B[SOB]32[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→7M►↕@♦U→4T►↕@♦D→3►↕*♦D•B→32►♥
Tail:    070000000106b5357ce89be17d8a03dadd3faf601ce183bc7c0a3c56120c8c61

Its answer, counter 2, with the content 23.5, bound to counter 1:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]D[SOB]3[EOW] [SOW]*[SOR]D[SOU]B[SOB]25[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→4T►↕@♦U→7M►↕@♦D→3►↕*♦D•B→25►♥
Tail:    080000000243fa37fec957c6daefdf93f7abe2cc0064ebed5f

An event from the responder, counter 3, with the content threshold_exceeded:

Pseudo:  [SOM] [SOW]![SOB]N[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]D[SOB]4[EOW] [SOW]*[SOR]D[SOU]B[SOB]39[EOW] [EOM]
Wire:    ☻↕!→N►↕@♦U→A7K2MQ►↕@♦U→4T►↕@♦U→7M►↕@♦D→4►↕*♦D•B→39►♥
Tail:    0900000003b4d38de60de4117caccc0009eaefb8c4154c660030af03253455a7
         72e94367066005

A.2 XK

Message 1:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]D[SOB]1[EOW] [SOW]*[SOR]D[SOU]B[SOB]49[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→7M►↕@♦U→4T►↕@♦D→1►↕*♦D•B→49►♥
Tail:    045ac670db24b842b088a0fb9f2cfb5512e50b5963cc2108359f6e74e400ef16
         49f8a477ead6390e651be5dc24ad348631

Message 2:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]D[SOB]1[EOW] [SOW]*[SOR]D[SOU]B[SOB]49[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→4T►↕@♦U→7M►↕@♦D→1►↕*♦D•B→49►♥
Tail:    05915aa9cef82c558965fbc39fd77a0f5eb83f3c692a0a5ffc0b519022a838f4
         5dbd125c1cbdd49e401f3e899c606a3a08

Message 3:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]D[SOB]2[EOW] [SOW]*[SOR]D[SOU]B[SOB]65[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→7M►↕@♦U→4T►↕@♦D→2►↕*♦D•B→65►♥
Tail:    06ad7b2551a43397f1a8b05575b7c2ac75d93cb197b766394211bedf59217424
         b7d55435485fe8657cba3da0a7db68655323d9b8d313e9dcc80ed1da0c8cdac3
         3b

The answer to message 3, with counter 1 and empty content:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]D[SOB]2[EOW] [SOW]*[SOR]D[SOU]B[SOB]21[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→4T►↕@♦U→7M►↕@♦D→2►↕*♦D•B→21►♥
Tail:    0800000001346f71fe5bcd4e44dfa5622092153f7b

A request, counter 1, with the content get_reading:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]D[SOB]3[EOW] [SOW]*[SOR]D[SOU]B[SOB]32[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→7M►↕@♦U→4T►↕@♦D→3►↕*♦D•B→32►♥
Tail:    0700000001995df7f948f177ed38eb55d77b40c0e18af92160ac6a50885ba384

Its answer, counter 2, with the content 23.5, bound to counter 1:

Pseudo:  [SOM] [SOW]![SOB]K[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]D[SOB]3[EOW] [SOW]*[SOR]D[SOU]B[SOB]25[EOW] [EOM]
Wire:    ☻↕!→K►↕@♦U→A7K2MQ►↕@♦U→4T►↕@♦U→7M►↕@♦D→3►↕*♦D•B→25►♥
Tail:    0800000002d6fa0632b407a0712f6e3bc79879eb2b9d0c1791

An event from the responder, counter 3, with the content threshold_exceeded:

Pseudo:  [SOM] [SOW]![SOB]N[EOW] [SOW]@[SOR]U[SOB]A7K2MQ[EOW] [SOW]@[SOR]U[SOB]4T[EOW] [SOW]@[SOR]U[SOB]7M[EOW] [SOW]@[SOR]D[SOB]4[EOW] [SOW]*[SOR]D[SOU]B[SOB]39[EOW] [EOM]
Wire:    ☻↕!→N►↕@♦U→A7K2MQ►↕@♦U→4T►↕@♦U→7M►↕@♦D→4►↕*♦D•B→39►♥
Tail:    090000000303f5ae15245ae0cb6ad620ed43246f5ac3f067c69397aa1bbd014c
         b2aeb30dee227d

Appendix B: Revision History

This appendix is non-normative.

Version Date Changes
0.4 November 2026 The contents list Appendix A and Appendix B as items of their own, where they ran together as one line. No requirement changed.
0.3 November 2026 "Level 1" names Version 1.9, which states what Section 8.2 relies on: a lost request sent again below a MID already passed is accepted (Level 1 Section 11.1.2).
0.2 November 2026 The title is Level 2 Specification - Security, and "Level 1" names its title and Version 1.7.
0.1 November 2026 The first draft.