mixnet/core/sphinx/
packet.rs

1// Copyright 2022 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21//! Sphinx packet format.
22//!
23//! Packets consist of the following, in order:
24//!
25//! - [`Header`]:
26//!   - Key-exchange public key ([`KxPublic`], alpha in the Sphinx paper).
27//!   - [`Mac`] (gamma in the Sphinx paper).
28//!   - Routing actions ([`Actions`], beta in the Sphinx paper).
29//! - [`Payload`] (delta in the Sphinx paper):
30//!   - [`PayloadData`].
31//!   - [`PayloadTag`] (for detecting tampering).
32//!
33//! For each hop, the routing actions field contains, in order:
34//!
35//! - A [`RawAction`]. Always a deliver action for the last hop and a forward action for earlier
36//!   hops.
37//! - If the [`RawAction`] is [`RAW_ACTION_FORWARD_TO_PEER_ID`], a [`PeerId`].
38//! - If the [`RawAction`] is a forward action, a [`Mac`] for the next hop.
39//! - If the [`RawAction`] is [`RAW_ACTION_DELIVER_REPLY`], a [`SurbId`].
40//! - If the [`RawAction`] is [`RAW_ACTION_DELIVER_COVER_WITH_ID`], a [`CoverId`].
41
42/// Size in bytes of a [`KxPublic`].
43pub const KX_PUBLIC_SIZE: usize = 32;
44/// Key-exchange public key.
45pub type KxPublic = [u8; KX_PUBLIC_SIZE];
46
47pub const MAC_SIZE: usize = 16;
48pub type Mac = [u8; MAC_SIZE];
49
50/// Maximum number of hops a packet can traverse. Sending a packet directly to the final
51/// destination node would count as one hop. Strictly speaking it is possible to construct packets
52/// that will traverse slightly more hops than this, but not using this crate.
53pub const MAX_HOPS: usize = 6;
54pub const RAW_MIXNODE_INDEX_SIZE: usize = 2;
55/// Raw mixnode index type, not guaranteed to be <= [`MAX_MIXNODE_INDEX`].
56pub type RawMixnodeIndex = u16;
57/// Maximum valid mixnode index.
58pub const MAX_MIXNODE_INDEX: RawMixnodeIndex = 0xfeff;
59pub const RAW_ACTION_SIZE: usize = RAW_MIXNODE_INDEX_SIZE; // A mixnode index means forward to that mixnode
60pub type RawAction = RawMixnodeIndex;
61pub const RAW_ACTION_FORWARD_TO_PEER_ID: RawAction = 0xff00;
62pub const RAW_ACTION_DELIVER_REQUEST: RawAction = 0xff01;
63pub const RAW_ACTION_DELIVER_REPLY: RawAction = 0xff02;
64pub const RAW_ACTION_DELIVER_COVER: RawAction = 0xff03;
65pub const RAW_ACTION_DELIVER_COVER_WITH_ID: RawAction = 0xff04;
66/// Size in bytes of a [`PeerId`].
67pub const PEER_ID_SIZE: usize = 32;
68/// Globally unique identifier for a network peer. This is treated as an opaque type.
69pub type PeerId = [u8; PEER_ID_SIZE];
70/// Maximum amount of padding that might need to be appended to the routing actions for length
71/// invariance at each hop.
72pub const MAX_ACTIONS_PAD_SIZE: usize = RAW_ACTION_SIZE + PEER_ID_SIZE + MAC_SIZE;
73pub const SURB_COVER_ID_SIZE: usize = 16;
74pub const SURB_ID_SIZE: usize = SURB_COVER_ID_SIZE;
75pub type SurbId = [u8; SURB_ID_SIZE];
76pub const COVER_ID_SIZE: usize = SURB_COVER_ID_SIZE;
77pub type CoverId = [u8; COVER_ID_SIZE];
78pub const ACTIONS_SIZE: usize = (MAX_HOPS * (RAW_ACTION_SIZE + MAC_SIZE)) +
79	PEER_ID_SIZE + // Allow one hop to use a peer ID
80	SURB_COVER_ID_SIZE // Last hop may have a SURB ID or a cover ID...
81	- MAC_SIZE; // ...but no next-hop MAC
82pub type Actions = [u8; ACTIONS_SIZE];
83
84pub const PAYLOAD_DATA_SIZE: usize = 2048;
85pub type PayloadData = [u8; PAYLOAD_DATA_SIZE];
86pub const PAYLOAD_TAG_SIZE: usize = 16;
87pub type PayloadTag = [u8; PAYLOAD_TAG_SIZE];
88pub const PAYLOAD_TAG: PayloadTag = [0; PAYLOAD_TAG_SIZE];
89
90pub const HEADER_SIZE: usize = KX_PUBLIC_SIZE + MAC_SIZE + ACTIONS_SIZE;
91pub type Header = [u8; HEADER_SIZE];
92pub const PAYLOAD_SIZE: usize = PAYLOAD_DATA_SIZE + PAYLOAD_TAG_SIZE;
93pub type Payload = [u8; PAYLOAD_SIZE];
94/// Size in bytes of a [`Packet`].
95pub const PACKET_SIZE: usize = HEADER_SIZE + PAYLOAD_SIZE;
96/// Type for packets sent between nodes. Note that all packets are the same size.
97pub type Packet = [u8; PACKET_SIZE];