# Notation and conventions These conventions apply, at least in theory, to all of the specification documents unless stated otherwise. > Remember, our specification documents > were once a collection of separate text files, > written separately > and edited over the course of years. > > While we are trying (as of 2023) > to edit them into consistency, > you should be aware that these conventions > are not now followed uniformly everywhere. ## MUST, SHOULD, and so on {#rfc2119} The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119). ## Data lengths {#data-lengths} Unless otherwise stated, all lengths are given as a number of 8-bit bytes. > All bytes are 8 bits long. > We sometimes call them "octets"; > the terms as used here are interchangeable. When referring to longer lengths, we use [SI binary prefixes](https://en.wikipedia.org/wiki/Binary_prefix) (as in "kibibytes", "mebibytes", and so on) to refer unambiguously to increments of 1024X bytes. > If you encounter a reference > to "kilobytes", "megabytes", or so on, > you cannot safely infer whether the author intended > a decimal (1000N) or binary (1024N) interpretation. > In these cases, it is better to revise the specifications. ## Integer encoding {#integers} Unless otherwise stated, all multi-byte integers are encoded in big-endian ("network") order. > For example, 4660 (0x1234), > when encoded as a two-byte integer, > is the byte 0x12 followed by the byte 0x34. (\[12 34\]) > > When encoded as a four-byte integer, > it is the byte 0x00, the byte 0x00, the byte 0x12, and the byte 0x34. > (\[00 00 12 34\]). ## Binary-as-text encodings {#binascii} When we refer to "base64", "base32", or "base16", we mean the encodings described in [RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648), with the following notes: - In base32, we never insert linefeeds in base32, and we omit trailing `=` padding characters. - In base64, we _sometimes_ omit trailing `=` padding characters, and we do not insert linefeeds unless explicitly noted. - We do not insert any other whitespace, except as specifically noted. Base 16 and base 32 are case-insensitive. Unless otherwise stated, implementations should accept any cases, and should produce a single uniform case. We sometimes refer to base16 as "hex" or "hexadecimal". > Note that as of 2023, in some places, the specs are not always > explicit about: > > - which base64 strings are multiline > - which base32 strings and base16 strings > should be generated in what case. > > This is something we should correct. ## Notation {#notation} ### Operations on byte strings {#ops} * `A | B` represents the concatenation of two binary strings `A` and `B`. ### Binary literals {#binary-literals} When we write a series of one-byte hexadecimal literals in square brackets, it represents a multi-byte binary string. > For example, > `[6f 6e 69 6f 6e 20 72 6f 75 74 69 6e 67]` > is a 13-byte sequence representing the unterminated ASCII string, > `onion routing`.