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}