hopr_crypto_packet/
lib.rs1pub mod sphinx;
20
21pub mod errors;
23pub mod expand;
25mod packet;
27mod por;
29mod types;
31mod validation;
33
34#[doc(hidden)]
35pub mod prelude {
36 pub use hopr_types::internal::routing::{HoprSenderId, HoprSurbId};
37
38 pub use super::*;
39 pub use crate::{
40 expand::{DirectKeyExpander, KeyExpander},
41 packet::{
42 HoprForwardedPacket, HoprIncomingPacket, HoprOutgoingPacket, HoprPacket, PacketRouting, PartialHoprPacket,
43 },
44 types::{
45 HOPR_PIX_COMMITMENT_PROOF_SIZE, HoprPixCommitmentProof, HoprPixGroupElement, PacketSignal, PacketSignals,
46 },
47 validation::validate_unacknowledged_ticket,
48 };
49}
50
51use hopr_protocol_pix::{PixGroup, PixScalar};
52use hopr_types::{crypto::prelude::*, internal::prelude::*, primitive::prelude::*};
53use sphinx::prelude::*;
54pub use sphinx::prelude::{ProtocolKeyIdMapper, ReplyOpener};
55
56pub type HoprSphinxSuite = Ed25519Suite;
60
61#[derive(Clone, Copy, Debug, PartialEq, Eq)]
63#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
64pub struct HoprSphinxHeaderSpec;
65
66impl SphinxHeaderSpec for HoprSphinxHeaderSpec {
67 type KeyId = HoprKeyIdent;
68 type PRG = ChaCha20;
69 type PacketReceiverData = HoprSenderId;
70 type Pseudonym = HoprPseudonym;
71 type RelayerData = por::ProofOfRelayString;
72 type SurbReceiverData = types::SurbReceiverInfo;
73 type UH = Poly1305;
74
75 const MAX_HOPS: std::num::NonZeroUsize = std::num::NonZeroUsize::new(INTERMEDIATE_HOPS + 1).unwrap();
76}
77
78pub type HoprKeyIdent = KeyIdent<4>;
80
81pub type HoprSurb = SURB<HoprSphinxSuite, HoprSphinxHeaderSpec>;
83
84pub type HoprReplyOpener = (HoprSurbId, ReplyOpener);
86
87pub(crate) const PAYLOAD_SIZE_INT: usize = DefaultSphinxPacketSize::USIZE - 1; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, Default)]
96#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
97pub struct HoprPixSpec;
98
99#[cfg(any(feature = "pix-secp256k1", not(feature = "pix-bjj")))]
100impl hopr_protocol_pix::PixSpec for HoprPixSpec {
101 type AddressPrivateKey = ChainKeypair;
102 type Cipher = ChaCha20;
103 type Curve = Secp256k1;
104 type DepositAddress = Address;
105 type Digest = Blake3;
106 type Pseudonym = SimplePseudonym;
107
108 const HASH_TO_SCALAR_SUITE_ID: &'static [u8] = b"Secp256k1_XMD:BLAKE3_SSWU_RO_";
109 const PIX_SUITE: hopr_protocol_pix::PixSuite = hopr_protocol_pix::PixSuite::Secp256k1;
110
111 fn group_to_deposit_address(group: PixGroup<Self>) -> Option<Self::DepositAddress> {
112 PublicKey::try_from(group.to_affine()).ok().map(|pk| pk.to_address())
113 }
114
115 fn scalar_to_private_key(scalar: PixScalar<Self>) -> Option<Self::AddressPrivateKey> {
116 ChainKeypair::from_secret(scalar.to_bytes().as_ref()).ok()
117 }
118}
119
120#[cfg(all(feature = "pix-bjj", not(feature = "pix-secp256k1")))]
121impl hopr_protocol_pix::PixSpec for HoprPixSpec {
122 type AddressPrivateKey = BjjKeypair;
123 type Cipher = ChaCha20;
124 type Curve = BabyJubJub;
125 type DepositAddress = BjjPublicKey;
126 type Digest = Blake3;
127 type Pseudonym = SimplePseudonym;
128
129 const HASH_TO_SCALAR_SUITE_ID: &'static [u8] = b"BabyJubJub_XMD:BLAKE3_SSWU_RO_";
130 const PIX_SUITE: hopr_protocol_pix::PixSuite = hopr_protocol_pix::PixSuite::BabyJubJub;
131
132 fn group_to_deposit_address(group: PixGroup<Self>) -> Option<Self::DepositAddress> {
133 BjjPublicKey::try_from(group).ok()
134 }
135
136 fn scalar_to_private_key(scalar: PixScalar<Self>) -> Option<Self::AddressPrivateKey> {
137 BjjKeypair::from_secret(scalar.to_bytes().as_ref()).ok()
138 }
139}
140
141pub type HoprEncryptedPartialSsaShare = hopr_protocol_pix::EncryptedPartialSsaShare<HoprPixSpec>;
143
144#[cfg(any(feature = "pix-secp256k1", not(feature = "pix-bjj")))]
146pub type HoprShareResolution = hopr_protocol_pix::ShareResolution<SimplePseudonym, ChainKeypair>;
147#[cfg(all(feature = "pix-bjj", not(feature = "pix-secp256k1")))]
148pub type HoprShareResolution = hopr_protocol_pix::ShareResolution<SimplePseudonym, BjjKeypair>;
149
150#[cfg(any(feature = "pix-secp256k1", not(feature = "pix-bjj")))]
152pub type HoprSsaCommitmentState = hopr_protocol_pix::SsaCommitmentState<SimplePseudonym, Address>;
153#[cfg(all(feature = "pix-bjj", not(feature = "pix-secp256k1")))]
154pub type HoprSsaCommitmentState = hopr_protocol_pix::SsaCommitmentState<SimplePseudonym, BjjPublicKey>;
155
156#[cfg(any(feature = "pix-secp256k1", not(feature = "pix-bjj")))]
166pub type HoprPixScalar = crypto_traits::elliptic_curve::Scalar<Secp256k1>;
167#[cfg(all(feature = "pix-bjj", not(feature = "pix-secp256k1")))]
168pub type HoprPixScalar = BabyJubJubScalar;
169
170#[cfg(any(feature = "pix-secp256k1", not(feature = "pix-bjj")))]
181pub type HoprPixGroupRepr = crypto_traits::elliptic_curve::array::Array<u8, crypto_traits::elliptic_curve::consts::U33>;
182#[cfg(all(feature = "pix-bjj", not(feature = "pix-secp256k1")))]
183pub type HoprPixGroupRepr = BabyJubJubCompressedPoint;
184
185#[cfg(test)]
186mod tests {
187 use sphinx::prelude::MetaPacket;
188
189 use super::*;
190 use crate::packet::HoprPacket;
191
192 #[test]
193 fn header_and_packet_lengths() {
194 let hopr_packet_len = HoprPacket::SIZE;
195 assert_eq!(
196 MetaPacket::<HoprSphinxSuite, HoprSphinxHeaderSpec, PAYLOAD_SIZE_INT>::PACKET_LEN + Ticket::SIZE,
197 hopr_packet_len
198 );
199
200 }
205
206 #[test]
207 fn packet_length() {
208 let packet_len = HoprPacket::SIZE;
209 assert_eq!(packet_len, 422 + PAYLOAD_SIZE_INT);
210 }
211
212 #[test]
213 fn header_length() {
214 let header_len = HoprSphinxHeaderSpec::HEADER_LEN;
215 assert_eq!(header_len, 241);
216 }
217
218 #[test]
219 fn surb_length() {
220 let surb_len = HoprSurb::SIZE;
221 assert_eq!(surb_len, 402);
223 assert!(HoprPacket::PAYLOAD_SIZE > surb_len * 2);
224 }
225
226 #[test]
227 fn max_surbs_per_packet_must_be_at_least_2() {
228 const _: () = {
229 assert!(HoprPacket::MAX_SURBS_IN_PACKET >= 2);
230 };
231 }
232}