nym_sphinx_params/
key_rotation.rs

1// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use thiserror::Error;
5
6#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
7#[repr(u8)]
8pub enum SphinxKeyRotation {
9    // for legacy packets, where there's no explicit information which key has been used
10    #[default]
11    Unknown = 0,
12
13    OddRotation = 1,
14
15    EvenRotation = 2,
16}
17
18impl SphinxKeyRotation {
19    pub fn from_key_rotation_id(rotation_id: u32) -> Self {
20        rotation_id.into()
21    }
22
23    pub fn is_unknown(&self) -> bool {
24        matches!(self, SphinxKeyRotation::Unknown)
25    }
26
27    pub fn is_even(&self) -> bool {
28        matches!(self, SphinxKeyRotation::EvenRotation)
29    }
30
31    pub fn is_odd(&self) -> bool {
32        matches!(self, SphinxKeyRotation::OddRotation)
33    }
34}
35
36#[derive(Debug, Error)]
37#[error("{received} is not a valid encoding of a sphinx key rotation")]
38pub struct InvalidSphinxKeyRotation {
39    received: u8,
40}
41
42// convert from particular rotation id into SphinxKeyRotation variant
43impl From<u32> for SphinxKeyRotation {
44    fn from(value: u32) -> Self {
45        if value == 0 || value == u32::MAX {
46            SphinxKeyRotation::Unknown
47        } else if value.is_multiple_of(2) {
48            SphinxKeyRotation::EvenRotation
49        } else {
50            SphinxKeyRotation::OddRotation
51        }
52    }
53}
54
55// convert from an encoded SphinxKeyRotation into particular variant
56// if value is actually provided, it MUST be one of the two. otherwise is invalid
57impl TryFrom<u8> for SphinxKeyRotation {
58    type Error = InvalidSphinxKeyRotation;
59
60    fn try_from(value: u8) -> Result<Self, Self::Error> {
61        match value {
62            _ if value == (Self::Unknown as u8) => Ok(Self::Unknown),
63            _ if value == (Self::OddRotation as u8) => Ok(Self::OddRotation),
64            _ if value == (Self::EvenRotation as u8) => Ok(Self::EvenRotation),
65            received => Err(InvalidSphinxKeyRotation { received }),
66        }
67    }
68}