]> Cypherpunks.ru repositories - nncp.git/commitdiff
Up to date NNCPE format
authorSergey Matveev <stargrave@stargrave.org>
Mon, 8 Nov 2021 13:29:04 +0000 (16:29 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Mon, 8 Nov 2021 13:29:04 +0000 (16:29 +0300)
doc/pkt/encrypted.texi

index b03614744dc08e867d046bf254c2bc74b45c366d..7b8ed21f56c3c2f226d7ab3335c62593815e2612 100644 (file)
@@ -7,11 +7,11 @@ storages and that are synchronized between TCP daemons.
 Each encrypted packet has the following header:
 
 @verbatim
 Each encrypted packet has the following header:
 
 @verbatim
-  +------------ HEADER --------------------+   +------------- ENCRYPTED -------------+
- /                                          \ /                                       \
-+--------------------------------------------+------+---------+----------...---+------+
-| MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | SIZE | BLOCK 0 | BLOCK 1  ...   | JUNK |
-+-------------------------------------/------\------+---------+----------...---+------+
+  +------------ HEADER --------------------+   +------ ENCRYPTED -----+
+ /                                          \ /                        \
++--------------------------------------------+---------+----------...---+-----...--+
+| MAGIC | NICE | SENDER | RCPT | EPUB | SIGN | BLOCK 0 | BLOCK 1  ...   |   OPAD   |
++-------------------------------------/------\---------+----------...---+-----...--+
                                      /        \
                       +-------------------------------------+
                       | MAGIC | NICE | SENDER | RCPT | EPUB |
                                      /        \
                       +-------------------------------------+
                       | MAGIC | NICE | SENDER | RCPT | EPUB |
@@ -22,7 +22,7 @@ Each encrypted packet has the following header:
 @headitem @tab XDR type @tab Value
 @item Magic number @tab
     8-byte, fixed length opaque data @tab
 @headitem @tab XDR type @tab Value
 @item Magic number @tab
     8-byte, fixed length opaque data @tab
-    @verb{|N N C P E 0x00 0x00 0x05|}
+    @verb{|N N C P E 0x00 0x00 0x06|}
 @item Niceness @tab
     unsigned integer @tab
     1-255, packet @ref{Niceness, niceness} level
 @item Niceness @tab
     unsigned integer @tab
     1-255, packet @ref{Niceness, niceness} level
@@ -40,17 +40,96 @@ Each encrypted packet has the following header:
     ed25519 signature for that packet's header over all previous fields.
 @end multitable
 
     ed25519 signature for that packet's header over all previous fields.
 @end multitable
 
-All following encryption is done in AEAD mode using
+Each @code{BLOCK} is AEAD-encrypted 128 KiB data. Last block can have
+smaller size. They are encrypted in AEAD mode using
 @url{https://cr.yp.to/chacha.html, ChaCha20}-@url{https://en.wikipedia.org/wiki/Poly1305, Poly1305}
 algorithms. Authenticated data is BLAKE3-256 hash of the unsigned
 @url{https://cr.yp.to/chacha.html, ChaCha20}-@url{https://en.wikipedia.org/wiki/Poly1305, Poly1305}
 algorithms. Authenticated data is BLAKE3-256 hash of the unsigned
-portion of the header (the same data used in the signature). Size is
-XDR-encoded unsigned hyper integer, carrying the payload size, encrypted
-as a single AEAD-block (with the tag) independently from the following
-blocks. It is encoded with the zero nonce.
+portion of the header (the same data used in the signature). Nonce is
+block's sequence number (64-bit integer starting at 0).
 
 
-Payload with possible padding is divided on 128 KiB blocks blocks. They
-are encrypted with the same authenticated data and increasing big-endian
-64-bit nonce, starting at 1.
+Concatenated plaintext of those blocks hold the following stream of data:
+
+@verbatim
++-----------+--------+---------------------+--------+
+|  PAYLOAD  |  SIZE  |  REST (OF PAYLOAD)  |  IPAD  |
++-----------+--------+---------------------+--------+
+            ^
+            |
+            +-- always aligned to the beginning of block
+@end verbatim
+
+Where @code{SIZE} is following XDR structure:
+
+@multitable @columnfractions 0.2 0.3 0.5
+@headitem @tab XDR type @tab Value
+@item Payload @tab
+    unsigned hyper integer @tab
+    Full payload size. @code{len(PAYLOAD) + len(REST)}
+@item Pad @tab
+    unsigned hyper integer @tab
+    Full padding size. @code{len(IPAD) + len(OPAD)}
+@end multitable
+
+@code{SIZE} is always at the beginning of the block. So payload and rest
+of it have variable length. Block containing @code{SIZE} is encrypted
+with the different key (@code{key=size}), to distinguish it from the
+"ordinary" ones (@code{key=full}).
+
+@code{IPAD} contains zeros and is shorter than single block. Padding is fully
+optional and is used only to hide the payload full size.
+
+It is acceptable to have either @code{PAYLOAD} or @code{REST} of it of
+zero length. For example:
+
+@verbatim
++------+-------------+
+| SIZE | PAYLOAD ... |
++------+-------------+
+ \------ BLOCK -----/
+         key=size
+
++------+-------------+------+
+| SIZE | PAYLOAD ... | IPAD |
++------+-------------+------+
+ \--------- BLOCK --------/
+            key=size
+
++--------------------------+    +------+-------------------+
+|          PAYLOAD         | .. | SIZE | IPAD ...           |
++--------------------------+    +------+-------------------+
+ \--------- BLOCK --------/      \--------- BLOCK --------/
+            key=full                        key=size
+
++--------------------------+    +------+-------------------+
+|          PAYLOAD         | .. | SIZE | PAYLOAD ...       |
++--------------------------+    +------+-------------------+
+ \--------- BLOCK --------/      \--------- BLOCK --------/
+            key=full                        key=size
+
++--------------------------+    +------+-------------+------+
+|          PAYLOAD         | .. | SIZE | PAYLOAD ... | IPAD |
++--------------------------+    +------+-------------+------+
+ \--------- BLOCK --------/      \--------- BLOCK --------/
+            key=full                        key=size
+
++--------------------------+    +------+-------------------+    +--------------------------+
+|          PAYLOAD         | .. | SIZE | PAYLOAD ...       | .. | PAYLOAD ...              |
++--------------------------+    +------+-------------------+    +--------------------------+
+ \--------- BLOCK --------/      \--------- BLOCK --------/      \--------- BLOCK --------/
+            key=full                        key=size                        key=full
+
++--------------------------+    +------+-------------------+    +-------------+-------------+
+|          PAYLOAD         | .. | SIZE | PAYLOAD ...       | .. | PAYLOAD ... | IPAD ...    |
++--------------------------+    +------+-------------------+    +-------------+------------+
+ \--------- BLOCK --------/      \--------- BLOCK --------/      \--------- BLOCK --------/
+            key=full                        key=size                        key=full
+@end verbatim
+
+@code{OPAD} is appended if @code{IPAD} (inside the block) has not enough
+length. @code{OPAD} is just an output of the XOF function. No encryption
+and explicit authentication is applied to it. XOF is just faster and can
+be computed deterministically on both ends -- you just have to
+authenticate its length.
 
 Each node has static @strong{exchange} and @strong{signature} keypairs.
 When node A want to send encrypted packet to node B, it:
 
 Each node has static @strong{exchange} and @strong{signature} keypairs.
 When node A want to send encrypted packet to node B, it:
@@ -63,17 +142,32 @@ When node A want to send encrypted packet to node B, it:
 @item takes remote node's exchange public key and performs
     Diffie-Hellman computation on this remote static public key and
     private ephemeral one
 @item takes remote node's exchange public key and performs
     Diffie-Hellman computation on this remote static public key and
     private ephemeral one
-@item derives 32-bytes AEAD encryption key with BLAKE3 derivation
-    function. Source key is the derived ephemeral key. Context is
-    @verb{|N N C P E 0x00 0x00 0x05|} magic number
+@item derives three keys using BLAKE3 derivation function from the
+    curve25519-derived ephemeral source key:
+    @itemize
+    @item @code{key=full} with the context of:
+        @verb{|N N C P E 0x00 0x00 0x06 <SP> F U L L|}
+    @item @code{key=size} with the context of:
+        @verb{|N N C P E 0x00 0x00 0x06 <SP> S I Z E|}
+    @item @code{key=pad} with the context of:
+        @verb{|N N C P E 0x00 0x00 0x06 <SP> P A D|}
+    @end itemize
 @item calculates authenticated data: it is BLAKE3-256 hash of the
     unsigned header (same used for signing)
 @item calculates authenticated data: it is BLAKE3-256 hash of the
     unsigned header (same used for signing)
-@item encrypts size, appends its authenticated ciphertext to the header
-    (with authenticated data, nonce=0)
-@item encrypts each payload block, appending its authenticated ciphertext
-    (with authenticated data, nonce starting at 1, increasing with each block)
-@item possibly appends any kind of "junk" noise data to hide real
-    payload's size from the adversary (generated using BLAKE3 XOF, with
-    the key derived from the ephemeral one and context string of
-    @verb{|N N C P E 0x00 0x00 0x05 <SP> P A D|})
+@item reads the payload by 128 KiB chunks. If it is enough data to fill
+    the entire 128 KiB block, then encrypt the chunk with
+    @code{key=full} key
+@item if there is not enough data, then payload is reaching the end.
+    @itemize
+    @item prepend @code{SIZE} structure to the finishing chunk of data.
+        All sizes at that time are known
+    @item produce block with @code{SIZE} even if there is no payload
+        data left
+    @item append remaining payload to the @code{SIZE}, if it is left
+    @item if there is padding, then fill current block to the end with
+        zeros (@code{IPAD})
+    @item encrypt the block with @code{key=size} key
+    @end itemize
+@item if there is more padding left (@code{OPAD}), then generate it with
+    BLAKE3 XOF function using the @code{key=pad} key
 @end enumerate
 @end enumerate