sphinx_packet/payload/
key.rs

1// Copyright 2025 Nym Technologies SA
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::constants::{
16    PAYLOAD_KEY_HKDF_INFO, PAYLOAD_KEY_HKDF_SALT, PAYLOAD_KEY_SEED_SIZE, PAYLOAD_KEY_SIZE,
17};
18use hkdf::Hkdf;
19use sha2::Sha256;
20use std::borrow::Borrow;
21
22pub type PayloadKey = [u8; PAYLOAD_KEY_SIZE];
23pub type PayloadKeySeed = [u8; PAYLOAD_KEY_SEED_SIZE];
24
25pub fn derive_payload_key(seed: &[u8; PAYLOAD_KEY_SEED_SIZE]) -> PayloadKey {
26    let hkdf = Hkdf::<Sha256>::new(Some(PAYLOAD_KEY_HKDF_SALT), seed);
27
28    let mut output = [0u8; PAYLOAD_KEY_SIZE];
29
30    // SAFETY: the length of the provided okm is within the allowed range
31    #[allow(clippy::unwrap_used)]
32    hkdf.expand(PAYLOAD_KEY_HKDF_INFO, &mut output).unwrap();
33
34    output
35}
36
37// helper trait to allow us to use either PayloadKey (as reference) directly or the seed (to create owned key)
38pub trait SphinxPayloadKey<'a> {
39    type Key: Borrow<PayloadKey>;
40
41    fn payload_key(&'a self) -> Self::Key;
42}
43
44impl<'a> SphinxPayloadKey<'a> for &'a PayloadKey {
45    type Key = &'a PayloadKey;
46
47    fn payload_key(&self) -> Self::Key {
48        self
49    }
50}
51
52impl<'a> SphinxPayloadKey<'a> for PayloadKey {
53    type Key = &'a PayloadKey;
54
55    fn payload_key(&'a self) -> Self::Key {
56        self
57    }
58}
59
60impl SphinxPayloadKey<'_> for &PayloadKeySeed {
61    type Key = PayloadKey;
62
63    fn payload_key(&self) -> Self::Key {
64        derive_payload_key(self)
65    }
66}
67
68impl SphinxPayloadKey<'_> for PayloadKeySeed {
69    type Key = PayloadKey;
70
71    fn payload_key(&self) -> Self::Key {
72        derive_payload_key(self)
73    }
74}