hopr_crypto_sphinx/
lib.rs

1//! This Rust crate contains implementation of the Sphinx packet format for the HOPR protocol.
2//!
3//! ## SPHINX shared keys derivation
4//! The architecture of the SPHINX shared key derivation is done generically, so it can work with any
5//! elliptic curve group for which CDH problem is hard. The generic Sphinx implementation only
6//! requires one to implement the `SphinxSuite` trait.
7//!
8//! The trait requires to have the following building blocks:
9//! - elliptic curve group ([GroupElement](shared_keys::GroupElement)) and corresponding the scalar type ([Scalar](shared_keys::Scalar))
10//! - type representing public and private keypair and their conversion to [Scalar](shared_keys::Scalar)
11//!   and [GroupElement](shared_keys::GroupElement) (by the means of the corresponding `From` trait implementation)
12//!
13//! Currently, there are the following [SphinxSuite](crate::shared_keys::SphinxSuite) implementations :
14//! - `Secp256k1Suite`: deprecated, used in previous HOPR versions
15//! - `Ed25519Suite`: simple implementation using Ed25519, used for testing
16//! - [X25519Suite](crate::ec_groups::X25519Suite) currently used, implemented using Curve25519 Montgomery curve for faster computation
17//!
18//! The implementation can be easily extended for different elliptic curves (or even arithmetic multiplicative groups).
19//! In particular, as soon as there's way to represent `Ed448` PeerIDs, it would be easy to create e.g. an `X448Suite`.
20
21/// Contains simple key derivation functions for different purposes
22mod derivation;
23/// Implementations of `SphinxSuite` trait for different elliptic curve groups
24mod ec_groups;
25/// Contains various errors returned from this crate.
26pub mod errors;
27/// Contains the main implementation of a SPHINX packet.
28mod packet;
29/// Implementation of the SPHINX header format
30mod routing;
31/// Derivation of shared keys for SPHINX header
32mod shared_keys;
33/// Contains Return Path and SURB-related types
34mod surb;
35
36pub mod prelude {
37    pub use crate::ec_groups::*;
38    pub use crate::packet::{
39        ForwardedMetaPacket, KeyIdMapper, MetaPacket, MetaPacketRouting, PaddedPayload, PartialPacket,
40    };
41    pub use crate::routing::SphinxHeaderSpec;
42    pub use crate::shared_keys::{SharedKeys, SharedSecret, SphinxSuite};
43    pub use crate::surb::*;
44}
45
46#[cfg(test)]
47pub(crate) mod tests {
48    use std::marker::PhantomData;
49    use std::num::{NonZero, NonZeroUsize};
50
51    use hopr_crypto_types::prelude::*;
52    use hopr_primitive_types::errors::GeneralError;
53    use hopr_primitive_types::prelude::*;
54
55    use crate::routing::SphinxHeaderSpec;
56
57    #[derive(Debug, Clone, Copy, PartialEq)]
58    pub(crate) struct WrappedBytes<const N: usize>(pub [u8; N]);
59
60    impl<const N: usize> Default for WrappedBytes<N> {
61        fn default() -> Self {
62            Self([0u8; N])
63        }
64    }
65
66    impl<'a, const N: usize> TryFrom<&'a [u8]> for WrappedBytes<N> {
67        type Error = GeneralError;
68
69        fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
70            value
71                .try_into()
72                .map(Self)
73                .map_err(|_| GeneralError::ParseError("WrappedBytes".into()))
74        }
75    }
76
77    impl<const N: usize> AsRef<[u8]> for WrappedBytes<N> {
78        fn as_ref(&self) -> &[u8] {
79            &self.0
80        }
81    }
82
83    impl<const N: usize> BytesRepresentable for WrappedBytes<N> {
84        const SIZE: usize = N;
85    }
86
87    pub(crate) struct TestSpec<K, const HOPS: usize, const RELAYER_DATA: usize>(PhantomData<K>);
88    impl<K, const HOPS: usize, const RELAYER_DATA: usize> SphinxHeaderSpec for TestSpec<K, HOPS, RELAYER_DATA>
89    where
90        K: AsRef<[u8]> + for<'a> TryFrom<&'a [u8], Error = GeneralError> + BytesRepresentable + Clone,
91    {
92        const MAX_HOPS: NonZeroUsize = NonZero::new(HOPS).unwrap();
93        type KeyId = K;
94        type Pseudonym = SimplePseudonym;
95        type RelayerData = WrappedBytes<RELAYER_DATA>;
96        type SurbReceiverData = WrappedBytes<53>;
97        type PRG = ChaCha20;
98        type UH = Poly1305;
99    }
100}