From 7253dbe611fa15af474c72811d6e4289c985c674 Mon Sep 17 00:00:00 2001
From: Striven <sg.striven@cutecat.club>
Date: Fri, 03 Apr 2026 19:09:17 +0000
Subject: [PATCH] Update PRUDP docs

---
 04_rendezvous/04_prudp_protocol.md |  128 ++++++++++++++++++++++++++++++++++++++----
 1 files changed, 114 insertions(+), 14 deletions(-)

diff --git a/04_rendezvous/04_prudp_protocol.md b/04_rendezvous/04_prudp_protocol.md
index 7d146b4..d23076e 100644
--- a/04_rendezvous/04_prudp_protocol.md
+++ b/04_rendezvous/04_prudp_protocol.md
@@ -1,37 +1,137 @@
 # RendezVous: PRUDP Protocol
 
-PRUDP probably stands for: "**P**rotected **R**eliable **U**ser **D**atagram **P**rotocol", as it is designed for adding connections, reliability, encryption and compression to UDP. To do this, it adds [connections](#connections), [ordering](#ordering), [fragmentation](#fragmentation) and [checksums](#checksums).
+PRUDP probably stands for **P**rotected **R**eliable **U**ser **D**atagram **P**rotocol, as it is designed for adding reliability, encryption and compression to UDP. To do this, it adds [connections](#connections), [acknowledgements](#acknowledgements), [ordering](#ordering), [fragmentation](#fragmentation), [compression](#compression), [encryption](#encryption) and [checksums](#checksums).
 
 ## Packets
+
+### Base Packet
+**Every** packet, sent by both the client and the server, has the following base information:
+
+| Name             | Description                                                                                                           | Type                                          |
+|------------------|-----------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
+| Source           | The [virtual stream](#connections) that the packet is being sent from.                                                | [`Stream`](#structure-stream)                 |
+| Destination      | The [virtual stream](#connections) that the packet is being sent to.                                                  | [`Stream`](#structure-stream)                 |
+| Type and Flags   | Type of the packet, and flags indicating how the client should treat this packet.                                     | [`Type and Flags`](#structure-type-and-flags) |
+| Session ID       | Unknown.                                                                                                              | `u8`                                          |
+| Packet Signature | Unknown.                                                                                                              | `u32`                                         |
+| Sequence ID      | A strictly monotonically increasing integer used for [acknowledgements](#acknowledgements) and [ordering](#ordering). | `u16`                                         |
+
 ### Packet: `SYN`
-
-### Packet: `CONNECT`
-
-This stage is used to derive a shared secret key.
+This packet establishes a connection with the server.
 
 #### Client->Server Payload
-| Name | Description | Type |
-|------|-------------|------|
-| Public Key | The client's _public key_. | [`Buffer`](./03_structure.md#structure-buffer) |
+| Name                 | Description | Type  |
+|----------------------|-------------|-------|
+| Connection Signature | Unknown.    | `u32` |
 
 #### Server->Client Payload
-| Name | Description | Type |
-|------|-------------|------|
-| Public Key Signature | Presumably, the client's _public key_ signed by the server's _private key_. | [`Buffer`](./03_structure.md#structure-buffer) |
-| Public Key | The server's _public key_. | [`Buffer`](./03_structure.md#structure-buffer) |
+| Name                 | Description | Type  |
+|----------------------|-------------|-------|
+| Connection Signature | Unknown.    | `u32` |
+
+### Packet: `CONNECT`
+This stage is used to execute a Diffie-Hellman key exchange, and then derive a shared secret key.
+
+The key exchange operation is $S = d \times Q$, where $S$ is the resulting key, $d$ is the server's private key, and $Q$ is the client's public key. The resulting `y` co-ordinate of this exchange is discarded.
+
+The shared key, used for `DATA` packet encryption and decryption, is derived using the first `16` bytes of a `SHA1` hash on the Diffie-Hellman exchange result.
+
+The server may also use this stage to affirm the client's [connection signature](#connections).
+
+#### Client->Server Payload
+| Name                 | Description                | Type                                                 |
+|----------------------|----------------------------|------------------------------------------------------|
+| Connection Signature | Unknown.                   | `u32`                                                |
+| Public Key           | The client's _public key_. | [`Public Key`](03_structure.md#structure-public-key) |
+
+#### Server->Client Payload
+| Name                 | Description                                                                                                                                                                                                                                               | Type                                                 |
+|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|
+| Connection Signature | Unknown.                                                                                                                                                                                                                                                  | `u32`                                                |
+| Public Key Signature | The server's _public key_ signed by the server's _certification private key_.                                                                                                                                                                             | [`Buffer`](03_structure.md#structure-buffer)         |
+| Public Key           | The server's _public key_.                                                                                                                                                                                                                                | [`Public Key`](03_structure.md#structure-public-key) |
+| Tag                  | A HMAC-SHA256 signature on both the [client's key](03_structure.md#structure-public-key) and the [server's key]([client's key](03_structure.md#structure-public-key)) concatenated, signed using the Diffie-Hellman exchange result (NOT the shared key). | [`Buffer`](03_structure.md#structure-buffer)         |
 
 ### Packet: `DATA`
+The whole data is _first_ fragmented, _then_ compressed, _then_ encrypted.
+
+This means that the data in this packet, if fragmented, should be [decrypted first](#encryption), then [de-compressed](#compression) (if applicable), and then re-assembled.
+
+The **compressed payload** (before encryption) is prefixed with a single byte indicating the compression ratio. `0` means that the remaining data is **not** compressed. The client appears to only ever use `0x02` for this byte, however.
+
+The **fragmented payload** (before compression) is suffixed with the 2-byte **sequence id** of the data packet being sent.
+
+#### Client->Server, Server->Client Payload
+| Name        | Description                                                                                                                                                     | Type  |
+|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|
+| Fragment ID | Used to re-assemble [fragmented](#fragmentation) data packets, starting from `1` (if multiple fragments exist), and ending in `0` to indicate a final fragment. | `u32` |
+| ...         | Encrypted and compressed data                                                                                                                                   | `any` |
+
 ### Packet: `DISCONNECT`
 ### Packet: `PING`
 
 ## Connections
 
-
+## Acknowledgements
 
 ## Ordering
 
+## Compression
+
+## Encryption
+
 ## Fragmentation
 
 ## Checksums
 
-## Packet Format
\ No newline at end of file
+## Packet Format
+
+## Structures
+
+### Structure: `Public Key`
+An **uncompressed** `SEC1` formatted key, **without** the preceeding compression tag (`0x04`).
+
+### Structure: `Stream`
+A packed `u8` containing
+| Name | Description                                       | Type                               |
+|------|---------------------------------------------------|------------------------------------|
+| Port | The [virtual port](#connections) for this stream. | `u4`                               |
+| Port | The type of stream that the connection is using.  | [`Stream Type`](#enum-stream-type) |
+
+### Structure: `Type and Flags`
+A packed `u8` containing
+| Name      | Description                                                                                                                                                                                                          | Type                               |
+|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|
+| Type      | The type of packet that is being sent.                                                                                                                                                                               | [`Packet Type`](#enum-packet-type) |
+| Ack       | This packet is an [acknowledgement](#acknowledgements) packet for a reliable packet sent by the recipient.                                                                                                           | `bool`                             |
+| Reliable  | This packet **must** be acknowledged by the recipient, or it will be re-sent.                                                                                                                                        | `bool`                             |
+| Need Ack  | The sender is expecting an acknowledgement for this packet.                                                                                                                                                          | `bool`                             |
+| Has Size  | The packet contains a `u16` size following the packet header (or, for [`SYN`](#packet-syn) and [`CONNECT`](#packet-connect), after the connection signature, and for [`DATA`](#packet-data), after the fragment ID). | `bool`                             |
+| Multi Ack | Unknown, doesn't appear to be supported, but if a packet flagged with `Need Ack` has this flag, the recipient should send an `Ack` with this flag set too.                                                           | `bool`                             |
+
+### Enum: `Stream Type`
+A `u4` containing these values:
+
+| Name                  | Value |
+|-----------------------|-------|
+| `RV Authentication` | `2`   |
+| `RV Secure` | `3`   |
+| `Sandbox Management` | `4`   |
+| `NAT` | `5`   |
+| `Session Discovery` | `6`   |
+| `Nat Echo` | `7`   |
+
+> [!IMPORTANT]
+> Hyperscape appears to exclusively use the `RV Secure` (`3`) type.
+
+### Enum: `Packet Type`
+A `u3` containing these values:
+
+| Name                  | Value |
+|-----------------------|-------|
+| [`SYN`](#packet-syn) | `0`   |
+| [`CONNECT`](#packet-connect) | `1`   |
+| [`DATA`](#packet-data) | `2`   |
+| [`DISCONNECT`](#packet-disconnect) | `3`   |
+| [`PING`](#packet-ping) | `4`   |
+| [`USER`](#packet-user) | `6`   |
\ No newline at end of file

--
Gitblit v1.10.0