This document represents Protocol Version 0xFF.
Pest is a peer-to-peer network protocol intended for IRC-style chat. It is designed for decentralization of control, resistance to natural and artificial interference, and fits-in-head mechanical simplicity -- in that order.
Pest explicitly rejects the inherently-centralizing concepts of IRC (not even speaking of the even more noxious "walled-garden" atrocities perpetrated in recent years.) In place of IRC's collectivist concept of the server, every Pest user instead inhabits a stand-alone station of which he is the sole operator. Pest stations exchange authenticably-encrypted messages exclusively with an operator-configured set of peers.
An IRC server is typically inhabited by a multitude of casual users and policed by a small group of privileged curators. A Pest station, on the other hand, is used exclusively by -- and is under the total control of -- one person: its operator.
Pest stations organize into nets. A net is a group of station operators who have a common interest. An operator who wishes to join a net must peer with at least one existing station on that net.
A broadcast message sent by one member of a net will be received by every other member. Nets may easily and organically undergo schismatic splits, or, on the contrary, unite into larger nets, as desired by their participants.
To join a Pest net, an operator must simply find one or more existing members of that net who would peer with his station, and securely exchange a small amount of information.
He may choose any handle he likes, so long as it does not collide with that of a peer. Importantly, one person may easily operate multiple Pest stations, and inhabit multiple disjoint nets; and may use, if he wishes, a different handle on each net.
All Pest messages are authenticable -- a station will only accept a message if it carries a valid signature from a WOT peer (though in some cases, the message may not have been authored by that peer.)
However, they are also repudiatable (i.e. non-opposable) -- since all packet signatures are produced with symmetric keys, the recipient of a message cannot, at any point in time, prove to a third party that he was not in fact the author of that message.
Of course, Pest does not somehow prevent operators from creating opposably-signed messages using other software and transmitting them to their peers, on the rare occasions which actually call for this.
Because Pest does not impose -- unlike IRC -- a hierarchical structure of control, it offers no direct equivalents to IRC's "kick" and "ban". An annoying, tedious, or habitually-spamming station operator is instead to be, at first -- warned by his fellows; then -- ignored via Usenet-style killfiles, and -- if he proves incorrigible -- unpeered by his peers. In the end, the malefactor will find himself where he belongs: either alone or in the company of his own kind.
Pest broadcast messages are flood-routed -- i.e. they traverse all available propagation paths. Unlike IRC relays, Pest stations may be connected in any topology their operators prefer; concretely, loops are permitted, in the interest of decentralization.
Infinite packet storms are prevented via deduplication at the station level -- rather than by prohibiting loops, or via a spanning tree protocol, or any other traditional routing schemes that enforce acyclic connection graphs by demanding the existence of "root nodes", "supernodes", centrally agreed-upon tables, etc.
Pest station operators are not merely permitted, but in fact are encouraged to form richly cyclic connection graphs for the highest attainable resiliency.
The operator of a Pest station -- who may be a human or a bot -- has absolute control of the station and its configuration.
A station communicates exclusively with:
The operator -- via the operator console, an IRC-compatible interface.
An operator-selected set of remote peer stations -- via datagrams.
In order for a pair of Pest stations to communicate, their operators must decide to peer them by agreeing1 on a shared secret key K. Additionally, at least one of the peers must have a routable, static address (here and below: IPv4 address and port, in a.b.c.d:p
notation), and it must be known to the other peer. Every packet sent by one peer to the other is signed/enciphered by the sender and verified/deciphered by the receiver using this K
.
If, at some future time, the operator of either station no longer wishes to continue in this relationship, he may terminate the peering unilaterally, and the two stations will then be said to have unpeered.
A Pest station may have any number of peers. One or more2 K
for each peer is kept in a data structure referred to as the station's WOT (Web of Trust). The operator may edit this structure at any time, and changes take effect immediately. The WOT is never altered by the station except by direct command of the operator.
A Pest station has another data structure, the AT (Address Table), which holds the last known address3 of each WOT peer. Like the WOT, the AT may also be edited by the operator at any time. Unlike the WOT, the AT is automatically updated by the station when a valid (per K
) packet is received from a peer who is transmitting from a new IP.
Addresses in the AT play no role in the authentication of incoming packets: which peer a packet originated from is determined solely using the WOT. Rather, the AT is used exclusively for determining where to send outgoing packets.
A Pest station is controlled by its operator through the operator console -- an interface implementing a minimal subset of the classical IRC protocol.
Traditional IRC offers no provisions for secure authentication or encryption; hence, it is recommended that a Pest station and its IRC client reside in one physical machine. Alternatively, they may run on separate machines and connect via an SSH tunnel or similar mechanism.
Per RFC-1459, an IRC message shall not exceed 512 bytes in length, including the mandatory CR-LF terminator. Thus, there are 510 bytes available for a command entered into the console (including its parameters); and similarly for any message emitted via the console.
Control commands allow a Pest station's operator to review or modify the station's configuration. They follow the traditional IRC syntax (i.e. /COMMAND ARGUMENT
). Any such command may be issued at any time, and must take effect (including preserving any state change to persistent storage) immediately.
Responses to control commands will be emitted through the console in the form of IRC NOTICE messages.
The following basic set of control commands must be supported:
Command | Arguments | Description |
---|---|---|
WOT |
Display the current WOT, with complete (apart from keys) data concerning each peer. This data consists of the peer's handles; whether the peer is paused; the timestamp of the most recent packet received from the peer; and the current address stored in the AT for the peer. Other info concerning the peer may be displayed. | |
WOT |
HANDLE |
Display all WOT data concerning the peer identified by HANDLE , including all known keys, starting with the most recently used, for that peer. |
PEER |
HANDLE |
Declare a new peer, identified by HANDLE . This command is required but not sufficient to establish communication with the peer (see also KEY and AT.) |
UNPEER |
HANDLE |
Permanently discard all stored data concerning the peer identified by HANDLE , including all keys and AT entries. |
PAUSE |
HANDLE |
Temporarily disable all communication with the peer identified by HANDLE , without discarding any data concerning said peer. |
UNPAUSE |
HANDLE |
Re-enable communication with the peer identified by HANDLE . If no corresponding PAUSE command had been previously issued, this command has no effect. |
KEY |
HANDLE KEY |
Add a KEY for the WOT peer identified by HANDLE . KEY is in all cases a base64-encoded 512-byte value, and may not previously exist anywhere in the WOT. HANDLE must have been previously issued in a PEER or AKA command. If HANDLE is unknown, a warning is displayed. |
UNKEY |
KEY |
Remove the given KEY from the WOT. However if KEY is any peer's only known key, the command has no effect and a warning is printed. |
GAG |
HANDLE |
Add HANDLE (which may not correspond to a WOT peer!) to the killfile. Incoming messages having a HANDLE matching a killfile entry will not be displayed to the console or relayed. |
UNGAG |
HANDLE |
Undo the effect of a previously-issued GAG command. If no corresponding command had been issued on HANDLE , this command has no effect. |
AT |
Display the current AT. | |
AT |
HANDLE |
Display the current AT entry for the peer identified by HANDLE . |
AT |
HANDLE ADDRESS |
Set the current ADDRESS in the AT for the WOT peer identified by HANDLE . In order for two peers to communicate, at least one of them must issue this command to add the other's address to his AT. Subsequently, this value will be updated as required as packets are received. |
RESOLVE |
HANDLE |
Resolve a fork afflicting the peer identified by HANDLE . |
The console will accept, at minimum, the following IRC-compatible commands:
Command | Arguments | Description |
---|---|---|
VERSION |
Display a description of the implementation and version of the protocol currently in use. | |
USER |
username hostname servername realname | Must be the first command issued upon connecting to the console. The string username must equal a preconfigured value stored on disk, or the console connection will be terminated. It is not used for any other purpose. None of the other parameters are used for any purpose, but may be present. |
PASS |
password | Must be the second command issued upon connecting to the console, and if found to be invalid, the console connection will be terminated. This is a password, or a derivative thereof; the exact authentication mechanism is unspecified. |
NICK |
HANDLE |
Must be the third command issued upon connecting to the console. HANDLE will be used in all messages originating from this station. HANDLE may not occur in the station's WOT. |
JOIN |
#pest |
Must be the fourth command issued upon connecting to the console. The argument must consist of the string "#pest" . |
PART |
string | Has no effect. |
PRIVMSG |
(#pest or HANDLE ) MESSAGE |
Transmit MESSAGE as a broadcast (if first argument is #pest ) or alternatively as a direct message to HANDLE . In the latter case, HANDLE must refer to a WOT peer for whom at least one key is known and an AT entry exists. If these conditions are not satisfied, a warning is displayed and the command has no effect. |
The console may support certain other commands:
Command | Arguments | Description |
---|---|---|
GENKEY |
Use the system TRNG to generate and display a new KEY suitable for use with KEY . No change is made to the WOT. |
|
AKA |
HANDLE1 HANDLE2 |
Permit the use of the string HANDLE2 synonymously with the previously-known HANDLE1 (which may in turn be the peer's original handle, or an alias added via this command.) |
UNAKA |
HANDLE |
Remove HANDLE from the WOT. However if it is any peer's only known handle, the command has no effect and a warning is displayed. |
ACHTUNG |
MESSAGE |
MESSAGE will be transmitted as a WOT circular, i.e. via a direct message addressed to each individual peer, exactly as if it had been issued via /PRIVMSG peername MESSAGE for each peer separately. |
BACKUP |
PATH |
The station will back up its current state (WOT, AT, killfile, and all other) to a file at the given PATH . |
RESTORE |
PATH |
The station will attempt to restore all state (WOT, AT, killfile, etc) from a file at the given PATH . |
SCRAM |
SCRAMPASS |
If sha512(SCRAMPASS) matches a preconfigured string stored on disk, the station will overwrite all in-memory and on-disk state with random bytes and shut down. This command may trigger other programmatic actions configured in advance by the operator, either before or after zapping all station state (e.g. in a before action -- emit a pre-defined /ACHTUNG deathsquad is here! goodbye friends! ). |
When a line of text is entered into the operator console, this text -- along with certain other data -- together will form a new message. This message may then be encoded into a packet and transmitted to peers; and these, in turn, will forward it to their operator consoles (and relay it to their peers) if the necessary conditions are met.
A Pest Message consists of 424 bytes, representing the following fields:
Bytes | Description |
---|---|
8 |
Timestamp |
32 |
SelfChain |
32 |
NetChain |
32 |
Speaker |
320 |
Text |
A 64-bit timestamp4 from the packet's originator station. A station relaying a Broadcast packet must preserve the original's timestamp.
A station must reject any incoming packet with a timestamp more than 15 minutes in either direction (i.e. into the past or the future) from the moment (per the station's clock) the packet was received.
A 256-bit hash5 of the most recent previous message originated by the originator of this message.
A station originating a broadcast message for the first time must set SelfChain
to zero.
If a station receives a broadcast message where SelfChain
is equal to zero, where Speaker
is e.g. nebuchadnezzar
, and this speaker had never been seen previously, it will emit to the operator console a warning of the following form:
Met nebuchadnezzar !
If however any messages with a Speaker
of nebuchadnezzar
have been seen previously, but this message's SelfChain
does not match the hash of the immediately-preceding one, the following warning shall be emitted to the console:
nebuchadnezzar forked! prev.: "blah..."
... where "blah..."
is the text of the previously-seen message pointed to by the SelfChain
(if available in the buffer; if not, a base-16 representation of SelfChain
is displayed instead.)
And nebuchadnezzar
is henceforth considered forked. While he is forked, the warning, in the above form, shall be emitted in the console (via NOTICE) after every message received where Speaker
is equal to nebuchadnezzar
.
The fork will be considered resolved only after the station operator executes the command /RESOLVE nebuchadnezzar
(after having a stern talk with the peer who had been relaying messages from the phony nebuchadnezzar
!)
A station must not reject a broadcast message simply because its Speaker
and SelfChain
indicate a state of forkage. Doing so would make recovery from certain failures (lost packets; data corruption) impossible, and constitutes a denial-of-service vector. However, station operators are encouraged to make use of out-of-band (e.g. GPG) methods to resolve a fork, should one happen to arise; and to mercilessly unpeer anyone found to be deliberately causing a fork under whatever pretext.
A 256-bit hash of the most recent previous message generated by the originator of this message in direct message sessions with this station.
In every other respect, the same rules as for broadcast messages apply.
A 256-bit hash of the most recent previous broadcast message seen by the originator of this message.
Currently this is not used for anything.
Must be set to zero.
A 32-byte field representing the Handle used by the originator of this packet. If this string consists of fewer than 32 characters, all unused bytes must be set to zero.
The (typically, human-readable) payload of the message. All unused trailing bytes must be set to zero.
A message, together with certain information which helps its recipient decide what to do with it, is termed a packet. Every packet starts life as red6 (i.e. plaintext).
A red packet consists of 444 bytes, representing the following fields:
Bytes | Description |
---|---|
16 |
Nonce |
1 |
Bounces |
1 |
Version |
1 |
Reserved |
1 |
Command |
424 |
Message |
16 bytes of garbage, exclusively for use as cipher nonce; obtained from TRNG, if possible.
This 1-byte field represents the number of times the message in this packet had been relayed between stations. A station must reject messages which have experienced more than a preconfigured number of bounces. The recommended cutoff value is 3.
This is a 1-byte field representing a "degrees Kelvin" (i.e. decrementing) version. (See version.)
This 1-byte field must equal 0.
This 1-byte field represents the intended purpose of the message M carried by the packet, as stated by its originator, and must have one of these values:
Value | Command | Description |
---|---|---|
0x00 |
Broadcast | The message is to be relayed to the entire net. |
0x01 |
Direct | The message is strictly for the addressee, and is not intended to be relayed. |
0x02 |
Reserved | |
... | ... | Packet is rejected |
0xFE |
Reserved | |
0xFF |
Ignore | A station may transmit garbage messages to its peers, to frustrate traffic analysis by snoops. In such cases, M will consist of arbitrary random bytes, obtained from a TRNG if possible. A recipient of such a message may relay it to an arbitrary subset of his WOT. The receipt by a station of a garbage message must not result in any console output. |
A Pest message can be either:
Direct -- Intended for a single recipient.
Broadcast -- Intended for the widest possible dissemination. A broadcast message may be either immediate or hearsay.
A message which is marked direct is sent to a single peer. A broadcast message is sent to every peer in the originator station's WOT, and will be propagated to their peers, and so on.
A broadcast message will often reach stations which are not in its originator's WOT. From the point of view of these stations, such a message is termed hearsay; and, when it is forwarded to an operator console, it is specially marked so as to distinguish it from an immediate message.
Prior to leaving a station, a red packet must be ciphered and signed using a K
found in the WOT for the peer who is to receive it. After this happens, the packet is referred to as black.
A black Pest packet consists of 508 bytes (excluding IP and UDP headers) representing the following fields:
Bytes | Description |
---|---|
444 | Ciphertext |
64 | Signature |
A third party without knowledge of K
is unable to read such a packet; to distinguish it from arbitrary random noise; or to generate a spurious replacement (including via replay, in whole or in part, of a previously-sent packet) that could be accepted by the addressee.
Every incoming (without exception, black) packet has its Signature
verified against each K
in the receiving station's WOT, in random order.
If verification of the packet against a given K
succeeds, it is then known to have been signed by the peer associated with that K
. The packet is then decrypted (with K
) and becomes red once again; at this point, the station is able to process the message it carried.
However, if none of the attempted verifications succeed, the packet is considered "martian" and silently discarded7. The receipt of a martian packet has absolutely no effect on a station, aside from wasting a small amount of CPU time. This provides a reasonable degree of DDOS resistance. A station may keep inexpensive statistical counters of martian packets.
When a line of text is entered by the station operator into the operator's console, the station is termed the originator of the message.
There are two possible scenarios:
Suppose a station operator using the handle shalmaneser
had issued the command /PRIVMSG nebuchadnezzar Come to tea.
the following actions will be performed:
nebuchadnezzar
will be located. (If one such does not exist, or nebuchadnezzar
is currently paused, nothing further happens, and a warning will be emitted to the console.)K
for nebuchadnezzar
will be located. (If no keys are known for nebuchadnezzar
, nothing further happens, and a warning will be emitted to the console.)K
will be separated into K(S)
-- the first 32 bytes of K
being the signing key, and K(C)
-- the cipher key (the last 32 bytes of K
.)nebuchadnezzar
will be located. (If one such does not exist... see above.)A red packet will be created, where:
Bytes | Description | Value |
---|---|---|
16 |
Nonce |
random bytes |
1 |
Bounces |
0 |
1 |
Version |
255 |
1 |
Reserved |
0 |
1 |
Command |
0x01 (Direct Message) |
424 |
Message |
as given below: |
Bytes | Description | Value |
---|---|---|
8 |
Timestamp |
shalmaneser 's current time |
32 |
SelfChain |
hash of shalmaneser 's previous direct message to nebuchadnezzar |
32 |
NetChain |
0 |
32 |
Speaker |
shalmaneser (padded with null bytes.) |
320 |
Text |
Come to tea. (Followed by 308 null bytes.) |
A black packet is created from the above red packet, where:
Bytes | Description | Value |
---|---|---|
444 | Ciphertext | The red packet, after ciphering with key K(C) . |
64 | Signature | The result of signing Ciphertext with K(S) . |
The black packet (henceforth -- packet) is stored in shalmaneser
's transmission queue.
nebuchadnezzar
's current address, determined in step 4.When an identical packet is echoed back from the above address, the transmission is considered complete. This is expected to happen within an operator-configurable period of time (recommended: 1 second.) If it does not, a warning will be displayed in shalmaneser
's console:
nebuchadnezzar did not ACK!
The packet is removed from shalmaneser
's transmission queue.
Suppose a station operator using the handle shalmaneser
had issued the command /PRIVMSG #pest Good morning, everyone!
the following actions will be performed:
P
in shalmaneser
's WOT:Pk
for P
will be located. (If no keys are known for P
, P
is simply ignored.)Pk
will be separated into Pk(S)
-- the first 32 bytes of Pk
, being the signing key and Pk(C)
-- the cipher key (the last 32 bytes of Pk
.)P
will be located. (If one such does not exist, P
will be ignored and we move on to the next peer.)For each peer, a red packet will be created, where:
Bytes | Description | Value |
---|---|---|
16 |
Nonce |
random bytes |
1 |
Bounces |
0 |
1 |
Version |
255 |
1 |
Reserved |
0 |
1 |
Command |
0x00 (Broadcast Message) |
424 |
Message |
as given below: |
Bytes | Description | Value |
---|---|---|
8 |
Timestamp |
shalmaneser 's current time |
32 |
SelfChain |
hash of shalmaneser 's previous broadcast message |
32 |
NetChain |
hash of the previous broadcast message seen by shalmaneser |
32 |
Speaker |
shalmaneser (padded with null bytes.) |
320 |
Text |
Good morning, everyone! (padded with null bytes.) |
A black packet is created from the above red packet, where:
Bytes | Description | Value |
---|---|---|
444 | Ciphertext | The red packet, after ciphering with key Pk(C) . |
64 | Signature | The result of signing Ciphertext with Pk(S) . |
The black packets (one for each peer) are stored in shalmaneser
's transmission queue.
Suppose a station operated by nebuchadnezzar
has received a packet. (The packet is from shalmaneser
, but nebuchadnezzar
does not know this yet, he has to first authenticate and decrypt it.) As all Pest packets traveling over the public internet are black packets, it has the structure:
Bytes | Description | Value |
---|---|---|
444 | Ciphertext | A red packet, ciphered with unknown key K(C) . |
64 | Signature | The result of signing Ciphertext with an unknown K(S) . |
nebuchadnezzar
's station will carry out the following procedure:
P
in nebuchadnezzar
's WOT, in random order:Pk
for P
will be located. (If no keys are known for P
, P
is simply ignored.)Pk
will be separated into Pk(S)
-- the first 32 bytes of Pk
, being the signing key and Pk(C)
-- the cipher key (the last 32 bytes of Pk
.)HMAC256(Ciphertext, Pk(S))
is compared to Signature
. If they do not match, the next P
is tried. If none match, the packet is declared martian and silently discarded.Pk(C)
is used to decrypt Ciphertext
and reproduce the original red packet.Timestamp
is compared to the current system time and if it is more than 15 minutes in the past or the future, the packet is declared stale and is silently discarded.Command
field...Continuing after the final step of the Common Procedure:
Speaker
field is compared to all handles known for the peer from whom the packet came (per step 4.) If none match, a warning is emitted, e.g.:
Direct message from 'bob' (shalmaneser)
... where the string in the parentheses is a WOT handle stored with the K
which had validated the packet in step 4.nebuchadnezzar
's console will display the Speaker
, followed by the Text
, e.g. shalmaneser: Come to tea.
in the standard format for IRC private messages.SelfChain
warning is displayed.Continuing after the final step of the Common Procedure:
Bounces
field of the red packet is compared to the operator-configured cutoff. If it is in excess of the cutoff, the packet is silently discarded.Speaker
field is compared to all handles known for the peer from whom the packet came (per step 4.). The next step of the algorithm depends on the result of this comparison.If the value of Speaker
corresponds to one of the handles stored in nebuchadnezzar
's WOT for the key K
which had validated the packet (in this case, shalmaneser
), the message is known as an immediate message. It is considered prima facie authentic, and displayed in nebuchadnezzar
's console in the standard form for IRC messages, marked with channel #pest
.
If the value of Speaker
does not correspond to any of the handles stored in nebuchadnezzar
's WOT for the key K
which had validated the packet, the message is known as a hearsay message.
Consider the case where the K
which had validated the message corresponds to shalmaneser
, but the Speaker
of the message is hammurabi
(and there is not a hammurabi
in nebuchadnezzar
's WOT.)
nebuchadnezzar
's station still knows which of his peers had sent in the message (shalmaneser
), because it had been signed and decrypted with that peer's K
. However, it also knows that the message had not been originated by shalmaneser
. (Or, if it had been, he is perhaps suffering from multiple personality disease.)
In any case, nebuchadnezzar
must be warned that the message is hearsay.
Therefore the Text
will be displayed in nebuchadnezzar
's console (in channel #pest
) in the following form:
hammurabi(shalmaneser): hey listen!
... where the handle in parentheses corresponds to the WOT peer from whom the packet had come.
Consider the case where the value of Speaker
in an incoming message does not correspond to any of the handles stored in the receiver's WOT for the key K
which had validated the packet, but in fact represents a handle used by another member of that WOT. This can happen if the immediate copy of that packet (i.e. received directly from its originator) has been lost or delayed in transit.
When such a packet is received and validated, it is placed into the station's embargo buffer and will remain there for an operator-configurable interval (recommended: 1 second) with the expectation that the immediate copy of the packet will arrive shortly, and "knock out" the embargoed hearsay version. If however the embargo interval elapses and the immediate copy of this packet is not received -- it will be placed into the deduplication buffer, emitted to the station's console, and rebroadcast to peers (see below.)
In both Immediate and Hearsay cases, after the message Text
is displayed in the receiver's console:
Bounces
field is incremented by 1.The base64-encoded key:
2Newlil7CEAcrLlLJhJaX1bOhYMzhbzX5s/UPYGXM3xTTry7sqvwYyp6ffinpQmgVVKZahjgIGILrPcAH2oI6A==
... when correctly decoded and broken into two 256-bit segments, represents the following (shown here in base-16) signing key:
d8d7b096297b08401cacb94b26125a5f56ce85833385bcd7e6cfd43d8197337c
... and the following cipher key:
534ebcbbb2abf0632a7a7df8a7a509a05552996a18e020620bacf7001f6a08e8
The base64-encoded key:
DpLg4cXUoraDQHaSfScfO7rV4jJGDKvq1RkpSnHRKKhhCZXMSvaq6QGKgcAbYriNXsw0bdiiz2/M0VeKL1Cb6g==
... when correctly decoded and broken into two 256-bit segments, represents the following (shown here in base-16) signing key:
0e92e0e1c5d4a2b6834076927d271f3bbad5e232460cabead519294a71d128a8
... and the following cipher key:
610995cc4af6aae9018a81c01b62b88d5ecc346dd8a2cf6fccd1578a2f509bea
TBD
Serpent
is the only symmetric cipher to be used.
All signatures are to be carried out using HMAC-256
.
All byte ordering in Pest, without exception, is little-endian unless otherwise stated.
If an operator wishes to run bots, guest accounts, etc., additional stations may be set up to peer with his primary one; on the same physical machine, if so desired.
Via secure means external to Pest, such as GPG, Peh, or an in-person meeting. ↩
A K
is to be generated using a TRNG whenever possible. Multiple keys associated with one peer are permitted. This is convenient when phasing out an old key in favour of a new one. The converse (the use of one key for multiple peers) is prohibited. When addressing outgoing packets to a peer for whom multiple values of K
are known, the one which validated the most recently-received packet is to be used. ↩
That is, the source address of the most recent packet received from this peer. ↩
Current time shall be defined as the value of a station's 64-bit monotonic epoch clock. Station operators must take measures to synchronize their clocks within 15 minutes, a precision entirely achievable without recourse to centralized time servers. ↩
In the current protocol: SHA256. The hash encompasses all message fields, in the order they are listed in the table. Any trailing padding bytes required by the hash are to equal zero. ↩
Americanism. ↩
All discarded packets are discarded silently; at no point is there to be any response to an invalid packet. ↩