From b5c8b69547cf32dbd8c9dc2d392326d19433a2fe Mon Sep 17 00:00:00 2001 From: Drazen Urch Date: Mon, 29 May 2023 10:05:11 +0200 Subject: [PATCH] Outfox integration (#3331) * Experiment with serde * Framed encoding serde POC * Outfox framing * Outfox rest compat (#3333) * Outfox forwarding compat * Tidy up interface * PacketSize compat * Address PR comments * Rebase on develop commit 342883fcbe41276f62fe18a8637978e82b05c945 Author: durch Date: Thu Apr 27 09:17:18 2023 +0200 Put back PacketType 1 commit 61a0ee5a193bd61343ffe86cce2e853321263a4d Author: Tommy Verrall Date: Wed Apr 26 16:37:29 2023 +0100 change output for cpu-cycle management logs commit 3956109c7ef4b5ec6d4b5e47070327a959e201dd Author: Tommy Verrall Date: Wed Apr 26 12:13:22 2023 +0100 change the workflow file to build with cpucycles commit 8d725b13c5cb0fd8456f26d577516e7bfd9d8b94 Author: durch Date: Mon Apr 24 13:14:58 2023 +0200 Outfox client compat commit 4d166c389bf65da6b8d1d360352650061e3a6c30 Author: durch Date: Fri Apr 21 00:30:46 2023 +0200 Address PR comments commit 145c3c1223af68d719a0004a5d81dc3ef0480409 Author: durch Date: Fri Apr 21 00:12:35 2023 +0200 Rename PacketMode commit cbd654d6fdfb05f7b1cb8d66bf81aebda76f7586 Author: Drazen Urch Date: Thu Apr 20 23:59:40 2023 +0200 Outfox rest compat (#3333) * Outfox forwarding compat * Tidy up interface * PacketSize compat commit e7be91a94cac7669471445236ff03165ebdf4fbc Author: durch Date: Wed Apr 19 16:36:48 2023 +0200 Remove serde cruft commit 582e7d566a5b7b94e64ee10d12994f2fef2e6cb1 Author: durch Date: Wed Apr 19 16:24:09 2023 +0200 Outfox framing commit 6464da5f01969d67d8efc8767d830218d8880efd Author: durch Date: Tue Apr 18 22:23:02 2023 +0200 Framing compat commit d5e77e499b197c043c827ad67ca4f02877b479f8 Author: durch Date: Tue Apr 18 18:18:54 2023 +0200 Framed encoding serde POC commit f086f9c35ab8158ca07c3b4a9be126c0a4559d10 Author: durch Date: Tue Apr 18 16:54:21 2023 +0200 Experiment with serde * Client tweaks * Speed up from_plaintext * SurbAcks * More work on the reciever end, and outfox format * Cleanup and fmt * Wrap up rebase * Happy clippy * Fix lock files * Final cleanup --- .gitignore | 3 +- Cargo.lock | 349 +- clients/native/src/client/mod.rs | 25 +- clients/native/src/websocket/handler.rs | 13 +- clients/socks5/src/commands/init.rs | 1 + clients/socks5/src/commands/mod.rs | 8 + clients/socks5/src/commands/run.rs | 4 + clients/webassembly/.gitignore | 1 - clients/webassembly/Cargo.lock | 5175 +++++++++++++++++ clients/webassembly/src/client/config.rs | 15 +- clients/webassembly/src/client/mod.rs | 19 +- common/async-file-watcher/src/lib.rs | 2 +- .../client-core/src/client/base_client/mod.rs | 20 +- .../src/client/base_client/storage/mod.rs | 16 +- .../src/client/cover_traffic_stream.rs | 3 +- .../src/client/inbound_messages.rs | 57 +- common/client-core/src/client/mix_traffic.rs | 6 +- .../acknowledgement_listener.rs | 2 +- .../input_message_listener.rs | 48 +- .../acknowledgement_control/mod.rs | 10 +- .../retransmission_request_listener.rs | 16 +- .../real_messages_control/message_handler.rs | 42 +- .../src/client/real_messages_control/mod.rs | 5 +- .../real_traffic_stream.rs | 7 +- .../client/replies/reply_controller/mod.rs | 6 +- .../src/client/transmission_buffer.rs | 2 +- common/client-core/src/config/mod.rs | 17 +- .../src/config/old_config_v1_1_13.rs | 3 +- .../src/config/persistence/key_pathfinder.rs | 10 +- .../client-libs/gateway-client/src/client.rs | 11 +- .../gateway-client/src/packet_router.rs | 7 +- .../client-libs/mixnet-client/src/client.rs | 33 +- .../mixnet-client/src/forwarder.rs | 6 +- .../src/packet_processor/error.rs | 5 +- .../src/packet_processor/processor.rs | 183 +- common/node-tester-utils/Cargo.toml | 1 + common/node-tester-utils/src/tester.rs | 10 +- common/nymsphinx/Cargo.toml | 3 - .../acknowledgements/src/identifier.rs | 10 +- .../acknowledgements/src/surb_ack.rs | 92 +- .../anonymous-replies/src/reply_surb.rs | 9 +- common/nymsphinx/cover/src/lib.rs | 43 +- common/nymsphinx/forwarding/Cargo.toml | 1 + common/nymsphinx/forwarding/src/packet.rs | 99 +- common/nymsphinx/framing/src/codec.rs | 233 +- common/nymsphinx/framing/src/packet.rs | 80 +- common/nymsphinx/params/src/lib.rs | 6 +- common/nymsphinx/params/src/packet_modes.rs | 46 - common/nymsphinx/params/src/packet_sizes.rs | 88 +- common/nymsphinx/params/src/packet_types.rs | 76 + common/nymsphinx/params/src/packet_version.rs | 4 +- common/nymsphinx/src/lib.rs | 2 +- common/nymsphinx/src/message.rs | 13 +- common/nymsphinx/src/preparer/mod.rs | 120 +- common/nymsphinx/src/preparer/payload.rs | 28 +- common/nymsphinx/src/receiver.rs | 45 - common/nymsphinx/types/Cargo.toml | 5 +- common/nymsphinx/types/src/lib.rs | 123 +- common/socks5-client-core/src/lib.rs | 17 +- common/socks5-client-core/src/socks/client.rs | 15 +- common/socks5-client-core/src/socks/server.rs | 16 +- common/topology/src/error.rs | 17 +- contracts/Cargo.lock | 260 +- gateway/gateway-requests/src/types.rs | 9 +- .../connection_handler/authenticated.rs | 7 +- .../receiver/connection_handler.rs | 8 +- .../receiver/packet_processing.rs | 4 +- mixnode/Cargo.toml | 1 + mixnode/src/main.rs | 7 +- .../node/listener/connection_handler/mod.rs | 10 +- .../connection_handler/packet_processing.rs | 4 +- mixnode/src/node/packet_delayforwarder.rs | 110 +- nym-api/src/network_monitor/chunker.rs | 86 + nym-api/src/network_monitor/mod.rs | 2 + nym-api/src/network_monitor/monitor/mod.rs | 14 +- .../src/network_monitor/monitor/preparer.rs | 6 +- nym-connect/desktop/Cargo.lock | 33 +- nym-outfox/Cargo.toml | 6 +- nym-outfox/src/constants.rs | 22 + nym-outfox/src/error.rs | 13 +- nym-outfox/src/format.rs | 153 +- nym-outfox/src/lib.rs | 1 + nym-outfox/src/lion.rs | 5 +- nym-outfox/src/packet.rs | 188 +- nym-outfox/tests/unittests.rs | 77 +- nym-wallet/Cargo.lock | 138 +- sdk/rust/nym-sdk/src/mixnet/client.rs | 6 +- sdk/rust/nym-sdk/src/mixnet/config.rs | 9 + sdk/rust/nym-sdk/src/mixnet/native_client.rs | 10 +- 89 files changed, 7566 insertions(+), 955 deletions(-) create mode 100644 clients/webassembly/Cargo.lock delete mode 100644 common/nymsphinx/params/src/packet_modes.rs create mode 100644 common/nymsphinx/params/src/packet_types.rs create mode 100644 nym-api/src/network_monitor/chunker.rs create mode 100644 nym-outfox/src/constants.rs diff --git a/.gitignore b/.gitignore index c42461127a..21ea8966e7 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,5 @@ storybook-static envs/qwerty.env .parcel-cache **/.DS_Store -cpu-cycles/libcpucycles/build \ No newline at end of file +cpu-cycles/libcpucycles/build +foxyfox.env \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index c344f44283..00c11606b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,6 +73,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.0.1" @@ -222,7 +233,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -233,7 +244,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -256,12 +267,9 @@ dependencies = [ [[package]] name = "atomic" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" -dependencies = [ - "autocfg 1.1.0", -] +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" [[package]] name = "atty" @@ -525,9 +533,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.1" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" [[package]] name = "byte-tools" @@ -626,9 +634,9 @@ dependencies = [ [[package]] name = "ciborium" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" dependencies = [ "ciborium-io", "ciborium-ll", @@ -637,15 +645,15 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" [[package]] name = "ciborium-ll" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" dependencies = [ "ciborium-io", "half", @@ -710,9 +718,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.2.1" +version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a19591b2ab0e3c04b588a0e04ddde7b9eaa423646d1b4a8092879216bf47473" +checksum = "1594fe2312ec4abf402076e407628f5c313e54c32ade058521df4ee34ecac8a8" dependencies = [ "clap 4.2.7", ] @@ -736,7 +744,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -763,16 +771,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "colorchoice" version = "1.0.0" @@ -814,9 +812,9 @@ dependencies = [ [[package]] name = "console-api" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57ff02e8ad8e06ab9731d5dc72dc23bef9200778eae1a89d555d8c42e5d4a86" +checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e" dependencies = [ "prost 0.11.9", "prost-types 0.11.9", @@ -826,9 +824,9 @@ dependencies = [ [[package]] name = "console-subscriber" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a3a81dfaf6b66bce5d159eddae701e3a002f194d378cbf7be5f053c281d9be" +checksum = "57ab2224a0311582eb03adba4caaf18644f7b1f10a760803a803b9b605187fc7" dependencies = [ "console-api", "crossbeam-channel", @@ -874,7 +872,7 @@ dependencies = [ "rand 0.8.5", "sha2 0.10.6", "subtle 2.4.1", - "time 0.3.20", + "time 0.3.21", "version_check", ] @@ -1304,50 +1302,6 @@ dependencies = [ "serde", ] -[[package]] -name = "cxx" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.15", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.15", -] - [[package]] name = "darling" version = "0.13.4" @@ -1623,7 +1577,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -1960,7 +1914,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -2089,7 +2043,7 @@ checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -2149,9 +2103,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes", "fnv", @@ -2192,7 +2146,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "ahash", + "ahash 0.7.6", ] [[package]] @@ -2201,7 +2155,16 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", ] [[package]] @@ -2215,11 +2178,11 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa" +checksum = "0761a1b9491c4f2e3d66aa0f62d0fba0af9a0e2852e4d48ea506632a4b56e6aa" dependencies = [ - "hashbrown 0.12.3", + "hashbrown 0.13.2", ] [[package]] @@ -2525,12 +2488,11 @@ dependencies = [ [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -2574,7 +2536,7 @@ checksum = "bfbcff6ae46750b15cc594bfd277b188cbddcfdc1817848f97f03f26f8625b9e" dependencies = [ "cfg-if", "js-sys", - "uuid 1.3.2", + "uuid 1.3.3", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2886,9 +2848,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.142" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libgit2-sys" @@ -2904,9 +2866,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "libsqlite3-sys" @@ -2931,15 +2893,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] - [[package]] name = "linux-raw-sys" version = "0.3.7" @@ -3145,9 +3098,9 @@ dependencies = [ [[package]] name = "notify" -version = "5.1.0" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ea850aa68a06e48fdb069c0ec44d0d64c8dbffa49bf3b6f7f0a901fdea1ba9" +checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" dependencies = [ "bitflags", "crossbeam-channel", @@ -3158,7 +3111,7 @@ dependencies = [ "libc", "mio", "walkdir", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3283,7 +3236,7 @@ dependencies = [ "sqlx 0.6.3", "tap", "thiserror", - "time 0.3.20", + "time 0.3.21", "tokio", "tokio-stream", "ts-rs", @@ -3413,7 +3366,7 @@ dependencies = [ "serde_json", "tap", "thiserror", - "time 0.3.20", + "time 0.3.21", "toml", "url", ] @@ -3485,7 +3438,7 @@ dependencies = [ "tap", "tempfile", "thiserror", - "time 0.3.20", + "time 0.3.21", "tokio", "tokio-stream", "tokio-tungstenite 0.14.0", @@ -3836,7 +3789,7 @@ dependencies = [ "serde-json-wasm", "serde_repr", "thiserror", - "time 0.3.20", + "time 0.3.21", "ts-rs", ] @@ -4017,6 +3970,7 @@ dependencies = [ "log", "nym-crypto", "nym-sphinx", + "nym-sphinx-params", "nym-task", "nym-topology", "rand 0.7.3", @@ -4058,8 +4012,10 @@ dependencies = [ "curve25519-dalek", "fastrand", "getrandom 0.2.9", + "log", + "rand 0.7.3", "rayon", - "sphinx-packet 0.1.0 (git+https://github.com/nymtech/sphinx.git)", + "sphinx-packet", "thiserror", "zeroize", ] @@ -4237,7 +4193,6 @@ dependencies = [ "log", "nym-crypto", "nym-mixnet-contract-common", - "nym-outfox", "nym-sphinx-acknowledgements", "nym-sphinx-addressing", "nym-sphinx-anonymous-replies", @@ -4336,6 +4291,7 @@ dependencies = [ "nym-sphinx-addressing", "nym-sphinx-params", "nym-sphinx-types", + "thiserror", ] [[package]] @@ -4372,7 +4328,9 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "sphinx-packet 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nym-outfox", + "sphinx-packet", + "thiserror", ] [[package]] @@ -4611,7 +4569,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4809,7 +4767,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics 0.10.0", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4886,7 +4844,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4902,22 +4860,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] @@ -5052,9 +5010,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" dependencies = [ "unicode-ident", ] @@ -5080,7 +5038,7 @@ checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", "version_check", "yansi", ] @@ -5175,9 +5133,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quote" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -5470,7 +5428,7 @@ checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -5507,9 +5465,9 @@ checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "reqwest" -version = "0.11.17" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64 0.21.0", "bytes", @@ -5610,7 +5568,7 @@ dependencies = [ "serde_json", "state", "tempfile", - "time 0.3.20", + "time 0.3.21", "tokio", "tokio-stream", "tokio-util", @@ -5672,7 +5630,7 @@ dependencies = [ "smallvec", "stable-pattern", "state", - "time 0.3.20", + "time 0.3.21", "tokio", "uncased", ] @@ -5881,12 +5839,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" - [[package]] name = "sct" version = "0.6.1" @@ -5922,9 +5874,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.2" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1" dependencies = [ "bitflags", "core-foundation", @@ -5935,9 +5887,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -5984,9 +5936,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] @@ -6022,13 +5974,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -6061,7 +6013,7 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -6267,29 +6219,6 @@ dependencies = [ "subtle 2.4.1", ] -[[package]] -name = "sphinx-packet" -version = "0.1.0" -source = "git+https://github.com/nymtech/sphinx.git#ca107d94360cdf8bbfbdb12fe5320ed74f80e40c" -dependencies = [ - "aes 0.7.5", - "arrayref", - "blake2 0.8.1", - "bs58", - "byteorder", - "chacha", - "curve25519-dalek", - "digest 0.9.0", - "hkdf 0.11.0", - "hmac 0.11.0", - "lioness", - "log", - "rand 0.7.3", - "rand_distr", - "sha2 0.9.9", - "subtle 2.4.1", -] - [[package]] name = "spin" version = "0.5.2" @@ -6363,7 +6292,7 @@ version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" dependencies = [ - "ahash", + "ahash 0.7.6", "atoi 0.4.0", "bitflags", "byteorder", @@ -6409,7 +6338,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ - "ahash", + "ahash 0.7.6", "atoi 1.0.0", "bitflags", "byteorder", @@ -6426,7 +6355,7 @@ dependencies = [ "futures-executor", "futures-intrusive", "futures-util", - "hashlink 0.8.1", + "hashlink 0.8.2", "hex", "indexmap", "itoa", @@ -6625,9 +6554,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" dependencies = [ "proc-macro2", "quote", @@ -6701,7 +6630,7 @@ dependencies = [ "subtle 2.4.1", "subtle-encoding", "tendermint-proto", - "time 0.3.20", + "time 0.3.21", "zeroize", ] @@ -6734,7 +6663,7 @@ dependencies = [ "serde", "serde_bytes", "subtle-encoding", - "time 0.3.20", + "time 0.3.21", ] [[package]] @@ -6762,7 +6691,7 @@ dependencies = [ "tendermint-config", "tendermint-proto", "thiserror", - "time 0.3.20", + "time 0.3.21", "tokio", "tracing", "url", @@ -6802,7 +6731,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -6828,9 +6757,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" dependencies = [ "itoa", "js-sys", @@ -6841,15 +6770,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" dependencies = [ "time-core", ] @@ -6881,9 +6810,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.0" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" dependencies = [ "autocfg 1.1.0", "bytes", @@ -6917,7 +6846,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -7040,14 +6969,13 @@ dependencies = [ [[package]] name = "tonic" -version = "0.8.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ - "async-stream", "async-trait", "axum", - "base64 0.13.1", + "base64 0.21.0", "bytes", "futures-core", "futures-util", @@ -7059,15 +6987,12 @@ dependencies = [ "percent-encoding", "pin-project", "prost 0.11.9", - "prost-derive 0.11.9", "tokio", "tokio-stream", - "tokio-util", "tower", "tower-layer", "tower-service", "tracing", - "tracing-futures", ] [[package]] @@ -7121,7 +7046,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" dependencies = [ "crossbeam-channel", - "time 0.3.20", + "time 0.3.21", "tracing-subscriber", ] @@ -7133,29 +7058,19 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - [[package]] name = "tracing-log" version = "0.1.3" @@ -7316,9 +7231,9 @@ dependencies = [ [[package]] name = "uncased" -version = "0.9.7" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" +checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" dependencies = [ "serde", "version_check", @@ -7457,9 +7372,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" +checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" dependencies = [ "getrandom 0.2.9", "wasm-bindgen", @@ -7491,7 +7406,7 @@ dependencies = [ "rustc_version 0.4.0", "rustversion", "thiserror", - "time 0.3.20", + "time 0.3.21", ] [[package]] @@ -7944,5 +7859,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] diff --git a/clients/native/src/client/mod.rs b/clients/native/src/client/mod.rs index 57d77a1d4d..5c612f8fdf 100644 --- a/clients/native/src/client/mod.rs +++ b/clients/native/src/client/mod.rs @@ -20,6 +20,7 @@ use nym_client_core::client::received_buffer::{ use nym_client_core::config::persistence::key_pathfinder::ClientKeyPathfinder; use nym_credential_storage::persistent_storage::PersistentStorage; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; +use nym_sphinx::params::PacketType; use nym_task::connections::TransmissionLane; use nym_task::TaskManager; use nym_validator_client::nyxd::QueryNyxdClient; @@ -63,6 +64,7 @@ impl SocketClient { client_state: ClientState, self_address: &Recipient, shutdown: nym_task::TaskClient, + packet_type: PacketType, ) { info!("Starting websocket listener..."); @@ -88,6 +90,7 @@ impl SocketClient { self_address, shared_lane_queue_lengths, reply_controller_sender, + Some(packet_type), ); websocket::Listener::new(config.get_listening_ip(), config.get_listening_port()) @@ -137,7 +140,8 @@ impl SocketClient { } let base_builder = self.create_base_client_builder().await?; - let mut started_client = base_builder.start_base().await?; + let packet_type = self.config.get_base().get_packet_type(); + let mut started_client = base_builder.start_base(packet_type).await?; let self_address = started_client.address; let client_input = started_client.client_input.register_producer(); let client_output = started_client.client_output.register_consumer(); @@ -150,6 +154,7 @@ impl SocketClient { client_state, &self_address, started_client.task_manager.subscribe(), + packet_type, ); info!("Client startup finished!"); @@ -164,7 +169,8 @@ impl SocketClient { } let base_builder = self.create_base_client_builder().await?; - let mut started_client = base_builder.start_base().await?; + let packet_type = self.config.get_base().get_packet_type(); + let mut started_client = base_builder.start_base(packet_type).await?; let address = started_client.address; let client_input = started_client.client_input.register_producer(); let client_output = started_client.client_output.register_consumer(); @@ -186,6 +192,7 @@ impl SocketClient { reconstructed_receiver, address, shutdown_notifier: started_client.task_manager, + packet_type, }) } } @@ -199,6 +206,7 @@ pub struct DirectClient { // we need to keep reference to this guy otherwise things will start dropping shutdown_notifier: TaskManager, + packet_type: PacketType, } impl DirectClient { @@ -219,7 +227,7 @@ impl DirectClient { /// well enough in local tests) pub async fn send_regular_message(&mut self, recipient: Recipient, message: Vec) { let lane = TransmissionLane::General; - let input_msg = InputMessage::new_regular(recipient, message, lane); + let input_msg = InputMessage::new_regular(recipient, message, lane, Some(self.packet_type)); self.client_input .input_sender @@ -238,7 +246,13 @@ impl DirectClient { reply_surbs: u32, ) { let lane = TransmissionLane::General; - let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane); + let input_msg = InputMessage::new_anonymous( + recipient, + message, + reply_surbs, + lane, + Some(self.packet_type), + ); self.client_input .input_sender @@ -252,7 +266,8 @@ impl DirectClient { /// well enough in local tests) pub async fn send_reply(&mut self, recipient_tag: AnonymousSenderTag, message: Vec) { let lane = TransmissionLane::General; - let input_msg = InputMessage::new_reply(recipient_tag, message, lane); + let input_msg = + InputMessage::new_reply(recipient_tag, message, lane, Some(self.packet_type)); self.client_input .input_sender diff --git a/clients/native/src/websocket/handler.rs b/clients/native/src/websocket/handler.rs index a0eebbf9be..3830a31894 100644 --- a/clients/native/src/websocket/handler.rs +++ b/clients/native/src/websocket/handler.rs @@ -14,6 +14,7 @@ use nym_client_core::client::{ use nym_client_websocket_requests::{requests::ClientRequest, responses::ServerResponse}; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; +use nym_sphinx::params::PacketType; use nym_sphinx::receiver::ReconstructedMessage; use nym_task::connections::{ ConnectionCommand, ConnectionCommandSender, ConnectionId, LaneQueueLengths, TransmissionLane, @@ -41,6 +42,7 @@ pub(crate) struct HandlerBuilder { self_full_address: Recipient, lane_queue_lengths: LaneQueueLengths, reply_controller_sender: ReplyControllerSender, + packet_type: Option, } impl HandlerBuilder { @@ -51,6 +53,7 @@ impl HandlerBuilder { self_full_address: &Recipient, lane_queue_lengths: LaneQueueLengths, reply_controller_sender: ReplyControllerSender, + packet_type: Option, ) -> Self { Self { msg_input, @@ -59,6 +62,7 @@ impl HandlerBuilder { self_full_address: *self_full_address, lane_queue_lengths, reply_controller_sender, + packet_type, } } @@ -73,6 +77,7 @@ impl HandlerBuilder { received_response_type: Default::default(), lane_queue_lengths: self.lane_queue_lengths.clone(), reply_controller_sender: self.reply_controller_sender.clone(), + packet_type: self.packet_type, } } } @@ -86,6 +91,7 @@ pub(crate) struct Handler { received_response_type: ReceivedResponseType, lane_queue_lengths: LaneQueueLengths, reply_controller_sender: ReplyControllerSender, + packet_type: Option, } impl Drop for Handler { @@ -160,7 +166,7 @@ impl Handler { }); // the ack control is now responsible for chunking, etc. - let input_msg = InputMessage::new_regular(recipient, message, lane); + let input_msg = InputMessage::new_regular(recipient, message, lane, self.packet_type); self.msg_input .send(input_msg) .await @@ -191,7 +197,8 @@ impl Handler { TransmissionLane::ConnectionId(id) }); - let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane); + let input_msg = + InputMessage::new_anonymous(recipient, message, reply_surbs, lane, self.packet_type); self.msg_input .send(input_msg) .await @@ -218,7 +225,7 @@ impl Handler { TransmissionLane::ConnectionId(id) }); - let input_msg = InputMessage::new_reply(recipient_tag, message, lane); + let input_msg = InputMessage::new_reply(recipient_tag, message, lane, self.packet_type); self.msg_input .send(input_msg) .await diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index 9009578f3c..3b4eb2cf11 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -91,6 +91,7 @@ impl From for OverrideConfig { no_cover: init_config.no_cover, nyxd_urls: init_config.nyxd_urls, enabled_credentials_mode: init_config.enabled_credentials_mode, + outfox: false, } } } diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index e792b842f3..2100e9915f 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -10,6 +10,7 @@ use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_config::{NymConfig, OptionalSet}; use nym_socks5_client_core::config::old_config_v1_1_13::OldConfigV1_1_13; use nym_socks5_client_core::config::{BaseConfig, Config}; +use nym_sphinx::params::PacketType; use std::error::Error; pub mod init; @@ -64,6 +65,7 @@ pub(crate) struct OverrideConfig { no_cover: bool, nyxd_urls: Option>, enabled_credentials_mode: Option, + outfox: bool, } pub(crate) async fn execute(args: &Cli) -> Result<(), Box> { @@ -80,9 +82,15 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box Config { + let packet_type = if args.outfox { + PacketType::Outfox + } else { + PacketType::Mix + }; config .with_base(BaseConfig::with_high_default_traffic_volume, args.fastmode) .with_base(BaseConfig::with_disabled_cover_traffic, args.no_cover) + .with_base(BaseConfig::with_packet_type, packet_type) .with_optional(Config::with_anonymous_replies, args.use_anonymous_replies) .with_optional(Config::with_port, args.port) .with_optional_custom_env_ext( diff --git a/clients/socks5/src/commands/run.rs b/clients/socks5/src/commands/run.rs index 26f2014d7a..09264adc58 100644 --- a/clients/socks5/src/commands/run.rs +++ b/clients/socks5/src/commands/run.rs @@ -68,6 +68,9 @@ pub(crate) struct Run { /// with bandwidth credential requirement. #[clap(long, hide = true)] enabled_credentials_mode: Option, + + #[clap(long, hide = true, action)] + outfox: bool, } impl From for OverrideConfig { @@ -80,6 +83,7 @@ impl From for OverrideConfig { no_cover: run_config.no_cover, nyxd_urls: run_config.nyxd_urls, enabled_credentials_mode: run_config.enabled_credentials_mode, + outfox: run_config.outfox, } } } diff --git a/clients/webassembly/.gitignore b/clients/webassembly/.gitignore index 90a2a4d375..5b7187cad5 100644 --- a/clients/webassembly/.gitignore +++ b/clients/webassembly/.gitignore @@ -1,6 +1,5 @@ /target **/*.rs.bk -Cargo.lock bin/ pkg/ wasm-pack.log diff --git a/clients/webassembly/Cargo.lock b/clients/webassembly/Cargo.lock new file mode 100644 index 0000000000..fb60a42854 --- /dev/null +++ b/clients/webassembly/Cargo.lock @@ -0,0 +1,5175 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array 0.14.7", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if 1.0.0", + "cipher 0.3.0", + "cpufeatures", + "ctr 0.8.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if 1.0.0", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +dependencies = [ + "aead", + "aes 0.8.2", + "cipher 0.4.4", + "ctr 0.9.2", + "ghash", + "subtle 2.4.1", +] + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.9", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "argon2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95c2fcf79ad1932ac6269a738109997a83c227c09b75842ae564dc8ede6a861c" +dependencies = [ + "base64ct", + "blake2 0.10.6", + "password-hash", +] + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "atoi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bip32" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f" +dependencies = [ + "bs58", + "hmac 0.11.0", + "k256", + "once_cell", + "pbkdf2", + "rand_core 0.6.4", + "ripemd160", + "sha2 0.9.9", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "unicode-normalization", + "zeroize", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" +dependencies = [ + "byte-tools", + "crypto-mac 0.7.0", + "digest 0.8.1", + "opaque-debug 0.2.3", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "blake3" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if 1.0.0", + "constant_time_eq", + "digest 0.10.6", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding", + "generic-array 0.14.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "bls12_381" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54757888b09a69be70b5ec303e382a74227392086ba808cb01eeca29233a2397" +dependencies = [ + "digest 0.9.0", + "ff 0.10.1", + "group 0.10.0", + "pairing 0.20.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "bls12_381" +version = "0.6.0" +source = "git+https://github.com/jstuczyn/bls12_381?branch=gt-serialisation#10fb6f700bfda17c8475af3bfd31e3fec15f2278" +dependencies = [ + "digest 0.9.0", + "ff 0.11.1", + "group 0.11.0", + "pairing 0.21.0", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2 0.9.9", +] + +[[package]] +name = "bumpalo" +version = "3.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" +dependencies = [ + "byteorder", + "keystream", +] + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if 1.0.0", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher 0.4.4", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clap" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +dependencies = [ + "clap_builder", + "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_complete" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1594fe2312ec4abf402076e407628f5c313e54c32ade058521df4ee34ecac8a8" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_complete_fig" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3af28956330989baa428ed4d3471b853715d445c62de21b67292e22cf8a41fa" +dependencies = [ + "clap", + "clap_complete", +] + +[[package]] +name = "clap_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "clap_lex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" + +[[package]] +name = "constant_time_eq" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cosmos-sdk-proto" +version = "0.12.3" +source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +dependencies = [ + "prost", + "prost-types", + "tendermint-proto", +] + +[[package]] +name = "cosmrs" +version = "0.7.1" +source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d" +dependencies = [ + "bip32", + "cosmos-sdk-proto", + "ecdsa", + "eyre", + "getrandom 0.2.9", + "k256", + "prost", + "prost-types", + "rand_core 0.6.4", + "serde", + "serde_json", + "subtle-encoding", + "tendermint", + "tendermint-rpc", + "thiserror", +] + +[[package]] +name = "cosmwasm-crypto" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970d1d705862179b5d7a233ae36f02f21c4ec1b8075fe60c77fc5b43471331fa" +dependencies = [ + "digest 0.9.0", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195" +dependencies = [ + "base64 0.13.1", + "cosmwasm-crypto", + "cosmwasm-derive", + "forward_ref", + "schemars", + "serde", + "serde-json-wasm", + "thiserror", + "uint", +] + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +dependencies = [ + "crc-catalog 1.1.1", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog 2.2.0", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array 0.14.7", + "subtle 2.4.1", +] + +[[package]] +name = "ct-logs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" +dependencies = [ + "sct 0.6.1", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher 0.3.0", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher 0.4.4", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "cw-storage-plus" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-utils" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw2" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", +] + +[[package]] +name = "cw3" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b" +dependencies = [ + "cosmwasm-std", + "cw-utils", + "schemars", + "serde", +] + +[[package]] +name = "cw4" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd" +dependencies = [ + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", +] + +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown 0.12.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.7", +] + +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +dependencies = [ + "const-oid", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle 2.4.1", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dyn-clone" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" + +[[package]] +name = "ecdsa" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "serde", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "serde_bytes", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek", + "hashbrown 0.12.3", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "elliptic-curve" +version = "0.11.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "ff 0.11.1", + "generic-array 0.14.7", + "group 0.11.0", + "rand_core 0.6.4", + "sec1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "enum-iterator" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a0ac4aeb3a18f92eaf09c6bb9b3ac30ff61ca95514fc58cbead1c9a6bf5401" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime 1.3.0", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "ff" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "ff" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flex-error" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" +dependencies = [ + "eyre", + "paste", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getset" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug 0.3.0", + "polyval", +] + +[[package]] +name = "git2" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c" +dependencies = [ + "bitflags", + "libc", + "libgit2-sys", + "log", + "url", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +dependencies = [ + "byteorder", + "ff 0.10.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "group" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +dependencies = [ + "byteorder", + "ff 0.11.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "h2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "handlebars" +version = "3.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4498fc115fa7d34de968184e473529abb40eeb6be8bc5f7faba3d08c316cb3e3" +dependencies = [ + "log", + "pest", + "pest_derive", + "quick-error 2.0.1", + "serde", + "serde_json", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown 0.11.2", +] + +[[package]] +name = "hashlink" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0761a1b9491c4f2e3d66aa0f62d0fba0af9a0e2852e4d48ea506632a4b56e6aa" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "headers" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +dependencies = [ + "base64 0.13.1", + "bitflags", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "hkdf" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" +dependencies = [ + "digest 0.9.0", + "hmac 0.11.0", +] + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.6", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error 1.2.3", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime 2.1.0", + "serde", +] + +[[package]] +name = "hyper" +version = "0.14.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-proxy" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" +dependencies = [ + "bytes", + "futures", + "headers", + "http", + "hyper", + "hyper-rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.22.0", + "tower-service", + "webpki 0.21.4", +] + +[[package]] +name = "hyper-rustls" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +dependencies = [ + "ct-logs", + "futures-util", + "hyper", + "log", + "rustls 0.19.1", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.22.0", + "webpki 0.21.4", + "webpki-roots 0.21.1", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexed_db_futures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfbcff6ae46750b15cc594bfd277b188cbddcfdc1817848f97f03f26f8625b9e" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "uuid 1.3.3", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "input_buffer" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" +dependencies = [ + "bytes", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipnet" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" + +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa", + "elliptic-curve", + "sec1", + "sha2 0.9.9", + "sha3", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keystream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.144" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" + +[[package]] +name = "libgit2-sys" +version = "0.13.5+1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e5ea06c26926f1002dd553fded6cfcdc9784c1f60feeb58368b4d9b07b6dba" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + +[[package]] +name = "libsqlite3-sys" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" + +[[package]] +name = "lioness" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" +dependencies = [ + "arrayref", + "blake2 0.8.1", + "chacha", + "keystream", +] + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.45.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "nym-api-requests" +version = "0.1.0" +dependencies = [ + "bs58", + "cosmrs", + "cosmwasm-std", + "getset", + "nym-coconut-interface", + "nym-mixnet-contract-common", + "schemars", + "serde", +] + +[[package]] +name = "nym-bandwidth-controller" +version = "0.1.0" +dependencies = [ + "bip39", + "nym-coconut-interface", + "nym-credential-storage", + "nym-credentials", + "nym-crypto", + "nym-network-defaults", + "nym-validator-client", + "rand 0.7.3", + "thiserror", + "url", +] + +[[package]] +name = "nym-bin-common" +version = "0.5.0" +dependencies = [ + "atty", + "clap", + "clap_complete", + "clap_complete_fig", + "log", + "pretty_env_logger", + "semver 0.11.0", + "vergen", +] + +[[package]] +name = "nym-client-core" +version = "1.1.14" +dependencies = [ + "async-trait", + "dashmap", + "dirs", + "futures", + "gloo-timers", + "humantime-serde", + "log", + "nym-bandwidth-controller", + "nym-config", + "nym-credential-storage", + "nym-crypto", + "nym-gateway-client", + "nym-gateway-requests", + "nym-network-defaults", + "nym-nonexhaustive-delayqueue", + "nym-pemstore", + "nym-sphinx", + "nym-task", + "nym-topology", + "nym-validator-client", + "rand 0.7.3", + "serde", + "serde_json", + "sqlx 0.6.3", + "tap", + "thiserror", + "time", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-timer", + "wasm-utils", + "zeroize", +] + +[[package]] +name = "nym-client-wasm" +version = "1.1.0" +dependencies = [ + "anyhow", + "async-trait", + "bs58", + "console_error_panic_hook", + "futures", + "js-sys", + "nym-bandwidth-controller", + "nym-client-core", + "nym-coconut-interface", + "nym-credential-storage", + "nym-credentials", + "nym-crypto", + "nym-gateway-client", + "nym-node-tester-utils", + "nym-sphinx", + "nym-sphinx-acknowledgements", + "nym-task", + "nym-topology", + "nym-validator-client", + "rand 0.7.3", + "serde", + "serde-wasm-bindgen", + "serde_json", + "thiserror", + "tokio", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "wasm-timer", + "wasm-utils", + "wee_alloc", + "zeroize", +] + +[[package]] +name = "nym-coconut" +version = "0.5.0" +dependencies = [ + "bls12_381 0.6.0", + "bs58", + "digest 0.9.0", + "ff 0.11.1", + "getrandom 0.2.9", + "group 0.11.0", + "itertools", + "nym-dkg", + "nym-pemstore", + "rand 0.8.5", + "serde", + "serde_derive", + "sha2 0.9.9", + "thiserror", +] + +[[package]] +name = "nym-coconut-bandwidth-contract-common" +version = "0.1.0" +dependencies = [ + "cosmwasm-std", + "nym-multisig-contract-common", + "schemars", + "serde", +] + +[[package]] +name = "nym-coconut-dkg-common" +version = "0.1.0" +dependencies = [ + "cosmwasm-std", + "cw-utils", + "nym-contracts-common", + "nym-multisig-contract-common", + "schemars", + "serde", +] + +[[package]] +name = "nym-coconut-interface" +version = "0.1.0" +dependencies = [ + "bs58", + "getset", + "nym-coconut", + "serde", + "thiserror", +] + +[[package]] +name = "nym-config" +version = "0.1.0" +dependencies = [ + "cfg-if 1.0.0", + "handlebars", + "log", + "nym-network-defaults", + "serde", + "toml", + "url", +] + +[[package]] +name = "nym-contracts-common" +version = "0.4.0" +dependencies = [ + "bs58", + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "nym-credential-storage" +version = "0.1.0" +dependencies = [ + "async-trait", + "log", + "sqlx 0.5.13", + "thiserror", + "tokio", +] + +[[package]] +name = "nym-credentials" +version = "0.1.0" +dependencies = [ + "bls12_381 0.5.0", + "cosmrs", + "nym-api-requests", + "nym-coconut-interface", + "nym-crypto", + "nym-validator-client", + "thiserror", +] + +[[package]] +name = "nym-crypto" +version = "0.3.0" +dependencies = [ + "aes 0.8.2", + "blake3", + "bs58", + "cipher 0.4.4", + "ctr 0.9.2", + "digest 0.10.6", + "ed25519-dalek", + "generic-array 0.14.7", + "hkdf 0.12.3", + "hmac 0.12.1", + "nym-pemstore", + "nym-sphinx-types", + "rand 0.7.3", + "serde", + "serde_bytes", + "subtle-encoding", + "thiserror", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "nym-dkg" +version = "0.1.0" +dependencies = [ + "bitvec", + "bls12_381 0.6.0", + "bs58", + "ff 0.11.1", + "group 0.11.0", + "lazy_static", + "nym-pemstore", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", + "serde_derive", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-gateway-client" +version = "0.1.0" +dependencies = [ + "futures", + "getrandom 0.2.9", + "log", + "nym-bandwidth-controller", + "nym-coconut-interface", + "nym-credential-storage", + "nym-crypto", + "nym-gateway-requests", + "nym-network-defaults", + "nym-pemstore", + "nym-sphinx", + "nym-task", + "nym-validator-client", + "rand 0.7.3", + "serde", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-timer", + "wasm-utils", +] + +[[package]] +name = "nym-gateway-requests" +version = "0.1.0" +dependencies = [ + "bs58", + "futures", + "generic-array 0.14.7", + "log", + "nym-coconut-interface", + "nym-credentials", + "nym-crypto", + "nym-pemstore", + "nym-sphinx", + "rand 0.7.3", + "serde", + "serde_json", + "thiserror", + "tungstenite", + "zeroize", +] + +[[package]] +name = "nym-group-contract-common" +version = "0.1.0" +dependencies = [ + "cw4", + "schemars", + "serde", +] + +[[package]] +name = "nym-mixnet-contract-common" +version = "0.5.0" +dependencies = [ + "bs58", + "cosmwasm-std", + "humantime-serde", + "log", + "nym-contracts-common", + "schemars", + "serde", + "serde-json-wasm", + "serde_repr", + "thiserror", + "time", +] + +[[package]] +name = "nym-multisig-contract-common" +version = "0.1.0" +dependencies = [ + "cosmwasm-std", + "cw-utils", + "cw3", + "cw4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "nym-name-service-common" +version = "0.1.0" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "nym-network-defaults" +version = "0.1.0" +dependencies = [ + "cfg-if 1.0.0", + "dotenvy", + "hex-literal", + "once_cell", + "serde", + "thiserror", + "url", +] + +[[package]] +name = "nym-node-tester-utils" +version = "0.1.0" +dependencies = [ + "futures", + "log", + "nym-crypto", + "nym-sphinx", + "nym-sphinx-params", + "nym-task", + "nym-topology", + "rand 0.7.3", + "serde", + "serde_json", + "thiserror", + "tokio", + "wasm-utils", +] + +[[package]] +name = "nym-nonexhaustive-delayqueue" +version = "0.1.0" +dependencies = [ + "futures-core", + "slab", + "tokio", + "tokio-stream", + "tokio-util", + "wasm-timer", +] + +[[package]] +name = "nym-outfox" +version = "0.1.0" +dependencies = [ + "blake3", + "chacha20", + "chacha20poly1305", + "curve25519-dalek", + "getrandom 0.2.9", + "log", + "rand 0.7.3", + "rayon", + "sphinx-packet", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-pemstore" +version = "0.2.0" +dependencies = [ + "pem", +] + +[[package]] +name = "nym-service-provider-directory-common" +version = "0.1.0" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "nym-sphinx" +version = "0.1.0" +dependencies = [ + "log", + "nym-crypto", + "nym-sphinx-acknowledgements", + "nym-sphinx-addressing", + "nym-sphinx-anonymous-replies", + "nym-sphinx-chunking", + "nym-sphinx-cover", + "nym-sphinx-forwarding", + "nym-sphinx-framing", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "rand_distr", + "thiserror", + "tokio", +] + +[[package]] +name = "nym-sphinx-acknowledgements" +version = "0.1.0" +dependencies = [ + "generic-array 0.14.7", + "nym-crypto", + "nym-pemstore", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "serde", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-sphinx-addressing" +version = "0.1.0" +dependencies = [ + "nym-crypto", + "nym-sphinx-types", + "serde", + "thiserror", +] + +[[package]] +name = "nym-sphinx-anonymous-replies" +version = "0.1.0" +dependencies = [ + "bs58", + "nym-crypto", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "serde", + "thiserror", + "wasm-bindgen", +] + +[[package]] +name = "nym-sphinx-chunking" +version = "0.1.0" +dependencies = [ + "log", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-types", + "rand 0.7.3", + "thiserror", +] + +[[package]] +name = "nym-sphinx-cover" +version = "0.1.0" +dependencies = [ + "nym-crypto", + "nym-sphinx-acknowledgements", + "nym-sphinx-addressing", + "nym-sphinx-chunking", + "nym-sphinx-forwarding", + "nym-sphinx-params", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "thiserror", +] + +[[package]] +name = "nym-sphinx-forwarding" +version = "0.1.0" +dependencies = [ + "nym-outfox", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-types", + "thiserror", +] + +[[package]] +name = "nym-sphinx-framing" +version = "0.1.0" +dependencies = [ + "bytes", + "nym-sphinx-params", + "nym-sphinx-types", + "thiserror", + "tokio-util", +] + +[[package]] +name = "nym-sphinx-params" +version = "0.1.0" +dependencies = [ + "nym-crypto", + "nym-sphinx-types", + "serde", + "thiserror", +] + +[[package]] +name = "nym-sphinx-routing" +version = "0.1.0" +dependencies = [ + "nym-sphinx-addressing", + "nym-sphinx-types", + "thiserror", +] + +[[package]] +name = "nym-sphinx-types" +version = "0.2.0" +dependencies = [ + "nym-outfox", + "sphinx-packet", + "thiserror", +] + +[[package]] +name = "nym-store-cipher" +version = "0.1.0" +dependencies = [ + "aes-gcm", + "argon2", + "generic-array 0.14.7", + "getrandom 0.2.9", + "rand 0.8.5", + "serde", + "serde_json", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-task" +version = "0.1.0" +dependencies = [ + "futures", + "log", + "thiserror", + "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "nym-topology" +version = "0.1.0" +dependencies = [ + "async-trait", + "bs58", + "log", + "nym-bin-common", + "nym-crypto", + "nym-mixnet-contract-common", + "nym-sphinx-addressing", + "nym-sphinx-routing", + "nym-sphinx-types", + "rand 0.7.3", + "thiserror", +] + +[[package]] +name = "nym-validator-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "base64 0.13.1", + "bip39", + "colored", + "cosmrs", + "cosmwasm-std", + "cw3", + "cw4", + "eyre", + "flate2", + "futures", + "itertools", + "log", + "nym-api-requests", + "nym-coconut-bandwidth-contract-common", + "nym-coconut-dkg-common", + "nym-coconut-interface", + "nym-config", + "nym-contracts-common", + "nym-group-contract-common", + "nym-mixnet-contract-common", + "nym-multisig-contract-common", + "nym-name-service-common", + "nym-network-defaults", + "nym-service-provider-directory-common", + "nym-vesting-contract", + "nym-vesting-contract-common", + "prost", + "reqwest", + "serde", + "serde_json", + "sha2 0.9.9", + "thiserror", + "tokio", + "url", + "zeroize", +] + +[[package]] +name = "nym-vesting-contract" +version = "1.4.0" +dependencies = [ + "cosmwasm-derive", + "cosmwasm-std", + "cw-storage-plus", + "cw2", + "nym-contracts-common", + "nym-mixnet-contract-common", + "nym-vesting-contract-common", + "schemars", + "semver 1.0.17", + "serde", + "thiserror", + "vergen", +] + +[[package]] +name = "nym-vesting-contract-common" +version = "0.6.0" +dependencies = [ + "cosmwasm-std", + "nym-contracts-common", + "nym-mixnet-contract-common", + "schemars", + "serde", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +dependencies = [ + "bitflags", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "pairing" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de9d09263c9966e8196fe0380c9dbbc7ea114b5cf371ba29004bc1f9c6db7f3" +dependencies = [ + "group 0.10.0", +] + +[[package]] +name = "pairing" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2e415e349a3006dd7d9482cdab1c980a845bed1377777d768cb693a44540b42" +dependencies = [ + "group 0.11.0", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "pbkdf2" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +dependencies = [ + "crypto-mac 0.11.1", +] + +[[package]] +name = "peg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" + +[[package]] +name = "pem" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" +dependencies = [ + "base64 0.13.1", + "once_cell", + "regex", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pest" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" +dependencies = [ + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "pest_meta" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.6", +] + +[[package]] +name = "pin-project" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der", + "spki", + "zeroize", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71adf41db68aa0daaefc69bb30bcd68ded9b9abaad5d1fbb6304c4fb390e083e" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b670f45da57fb8542ebdbb6105a925fe571b67f9e7ed9f47a06a84e72b4e7cc" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0a014229361011dc8e69c8a1ec6c2e8d0f2af7c91e3ea3f5b2170298461e68" +dependencies = [ + "bytes", + "prost", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.9", +] + +[[package]] +name = "rand_distr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" +dependencies = [ + "num-traits", + "rand 0.7.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.9", + "redox_syscall 0.2.16", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "base64 0.21.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rfc6979" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +dependencies = [ + "crypto-bigint", + "hmac 0.11.0", + "zeroize", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.17", +] + +[[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.1", + "log", + "ring", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +dependencies = [ + "log", + "ring", + "sct 0.7.0", + "webpki 0.22.0", +] + +[[package]] +name = "rustls-native-certs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" +dependencies = [ + "openssl-probe", + "rustls 0.19.1", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +dependencies = [ + "base64 0.21.0", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] +name = "ryu" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +dependencies = [ + "windows-sys 0.42.0", +] + +[[package]] +name = "schemars" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +dependencies = [ + "dyn-clone", + "indexmap", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +dependencies = [ + "der", + "generic-array 0.14.7", + "pkcs8", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2855b3715770894e67cbfa3df957790aa0c9edc3bf06efa1a84d77fa0839d1" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.163" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.163" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.96" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.6", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug 0.3.0", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +dependencies = [ + "digest 0.9.0", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "sphinx-packet" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" +dependencies = [ + "aes 0.7.5", + "arrayref", + "blake2 0.8.1", + "bs58", + "byteorder", + "chacha", + "curve25519-dalek", + "digest 0.9.0", + "hkdf 0.11.0", + "hmac 0.11.0", + "lioness", + "log", + "rand 0.7.3", + "rand_distr", + "sha2 0.9.9", + "subtle 2.4.1", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlformat" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" +dependencies = [ + "itertools", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +dependencies = [ + "sqlx-core 0.5.13", + "sqlx-macros 0.5.13", +] + +[[package]] +name = "sqlx" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +dependencies = [ + "sqlx-core 0.6.3", + "sqlx-macros 0.6.3", +] + +[[package]] +name = "sqlx-core" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" +dependencies = [ + "ahash 0.7.6", + "atoi 0.4.0", + "bitflags", + "byteorder", + "bytes", + "crc 2.1.0", + "crossbeam-queue", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink 0.7.0", + "hex", + "indexmap", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.19.1", + "sha2 0.10.6", + "smallvec", + "sqlformat 0.1.8", + "sqlx-rt 0.5.13", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki 0.21.4", + "webpki-roots 0.21.1", +] + +[[package]] +name = "sqlx-core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +dependencies = [ + "ahash 0.7.6", + "atoi 1.0.0", + "bitflags", + "byteorder", + "bytes", + "crc 3.0.1", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink 0.8.2", + "hex", + "indexmap", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.20.8", + "rustls-pemfile", + "sha2 0.10.6", + "smallvec", + "sqlformat 0.2.1", + "sqlx-rt 0.6.3", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki-roots 0.22.6", +] + +[[package]] +name = "sqlx-macros" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" +dependencies = [ + "dotenv", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2 0.10.6", + "sqlx-core 0.5.13", + "sqlx-rt 0.5.13", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +dependencies = [ + "dotenvy", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2 0.10.6", + "sqlx-core 0.6.3", + "sqlx-rt 0.6.3", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls 0.22.0", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls 0.23.4", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stringprep" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", +] + +[[package]] +name = "tendermint" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949" +dependencies = [ + "async-trait", + "bytes", + "ed25519", + "ed25519-dalek", + "flex-error", + "futures", + "k256", + "num-traits", + "once_cell", + "prost", + "prost-types", + "ripemd160", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.9.9", + "signature", + "subtle 2.4.1", + "subtle-encoding", + "tendermint-proto", + "time", + "zeroize", +] + +[[package]] +name = "tendermint-config" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd" +dependencies = [ + "flex-error", + "serde", + "serde_json", + "tendermint", + "toml", + "url", +] + +[[package]] +name = "tendermint-proto" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost", + "prost-types", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-rpc" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6" +dependencies = [ + "async-trait", + "bytes", + "flex-error", + "futures", + "getrandom 0.2.9", + "http", + "hyper", + "hyper-proxy", + "hyper-rustls", + "peg", + "pin-project", + "serde", + "serde_bytes", + "serde_json", + "subtle-encoding", + "tendermint", + "tendermint-config", + "tendermint-proto", + "thiserror", + "time", + "tokio", + "tracing", + "url", + "uuid 0.8.2", + "walkdir", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "time" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +dependencies = [ + "itoa", + "js-sys", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls 0.19.1", + "tokio", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.8", + "tokio", + "webpki 0.22.0", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e96bb520beab540ab664bd5a9cfeaa1fcd846fa68c830b42e2c8963071251d2" +dependencies = [ + "futures-util", + "log", + "pin-project", + "tokio", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "slab", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tungstenite" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fe8dada8c1a3aeca77d6b51a4f1314e0f4b8e438b7b1b71e3ddaca8080e4093" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "input_buffer", + "log", + "rand 0.8.5", + "sha-1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "universal-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +dependencies = [ + "crypto-common", + "subtle 2.4.1", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + +[[package]] +name = "uuid" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" +dependencies = [ + "getrandom 0.2.9", + "wasm-bindgen", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vergen" +version = "7.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447f9238a4553957277b3ee09d80babeae0811f1b3baefb093de1c0448437a37" +dependencies = [ + "anyhow", + "cfg-if 1.0.0", + "enum-iterator", + "getset", + "git2", + "rustc_version", + "rustversion", + "thiserror", + "time", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if 1.0.0", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d2fff962180c3fadf677438054b1db62bee4aa32af26a45388af07d1287e1d" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4683da3dfc016f704c9f82cf401520c4f1cb3ee440f7f52b3d6ac29506a49ca7" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "git+https://github.com/mmsinclair/wasm-timer?rev=b9d1a54ad514c2f230a026afe0dde341e98cd7b6#b9d1a54ad514c2f230a026afe0dde341e98cd7b6" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasm-utils" +version = "0.1.0" +dependencies = [ + "futures", + "getrandom 0.2.9", + "indexed_db_futures", + "js-sys", + "nym-store-cipher", + "serde", + "serde-wasm-bindgen", + "thiserror", + "tungstenite", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki 0.21.4", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki 0.22.0", +] + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek", + "rand_core 0.5.1", + "serde", + "zeroize", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] diff --git a/clients/webassembly/src/client/config.rs b/clients/webassembly/src/client/config.rs index 3e240966c2..ff6a6323a4 100644 --- a/clients/webassembly/src/client/config.rs +++ b/clients/webassembly/src/client/config.rs @@ -11,7 +11,7 @@ use nym_client_core::config::{ DebugConfig as ConfigDebug, GatewayConnection as ConfigGatewayConnection, ReplySurbs as ConfigReplySurbs, Topology as ConfigTopology, Traffic as ConfigTraffic, }; -use nym_sphinx::params::PacketSize; +use nym_sphinx::params::{PacketSize, PacketType}; use nym_validator_client::client::IdentityKey; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -34,6 +34,8 @@ pub struct Config { pub(crate) gateway: Option, pub(crate) debug: ConfigDebug, + + pub(crate) packet_type: PacketType, } #[wasm_bindgen] @@ -42,9 +44,18 @@ impl Config { pub fn new( id: String, validator_server: String, + packet_type: Option, gateway: Option, debug: Option, ) -> Self { + let packet_type = if let Some(packet_type) = packet_type { + match packet_type.as_str() { + "outfox" => PacketType::Outfox, + _ => PacketType::Mix, + } + } else { + PacketType::Mix + }; Config { id, nym_api_url: Some( @@ -55,6 +66,7 @@ impl Config { disabled_credentials_mode: true, gateway, debug: debug.map(Into::into).unwrap_or_default(), + packet_type, } } } @@ -97,6 +109,7 @@ impl From for ConfigTraffic { .disable_main_poisson_packet_distribution, primary_packet_size: PacketSize::RegularPacket, secondary_packet_size: use_extended_packet_size, + packet_type: None, } } } diff --git a/clients/webassembly/src/client/mod.rs b/clients/webassembly/src/client/mod.rs index 2464e75acd..baf72a7c85 100644 --- a/clients/webassembly/src/client/mod.rs +++ b/clients/webassembly/src/client/mod.rs @@ -23,6 +23,7 @@ use nym_client_core::client::inbound_messages::InputMessage; use nym_client_core::client::replies::reply_storage::browser_backend; use nym_client_core::config::{CoverTraffic, DebugConfig, Topology, Traffic}; use nym_credential_storage::ephemeral_storage::EphemeralStorage; +use nym_sphinx::params::PacketType; use nym_task::connections::TransmissionLane; use nym_task::TaskManager; use nym_topology::provider_trait::{HardcodedTopologyProvider, TopologyProvider}; @@ -52,6 +53,7 @@ pub struct NymClient { // even though we don't use graceful shutdowns, other components rely on existence of this struct // and if it's dropped, everything will start going offline _task_manager: TaskManager, + packet_type: Option, } #[wasm_bindgen] @@ -68,6 +70,7 @@ pub struct NymClientBuilder { bandwidth_controller: Option, EphemeralStorage>>, disabled_credentials: bool, + packet_type: Option, } #[wasm_bindgen] @@ -86,6 +89,7 @@ impl NymClientBuilder { on_message, bandwidth_controller: None, disabled_credentials: true, + packet_type: None, } } @@ -124,6 +128,7 @@ impl NymClientBuilder { }, ..Default::default() }, + packet_type: PacketType::Mix, }; NymClientBuilder { @@ -136,6 +141,7 @@ impl NymClientBuilder { bandwidth_controller: None, disabled_credentials: true, storage_passphrase: None, + packet_type: None, } } @@ -202,7 +208,8 @@ impl NymClientBuilder { base_builder = base_builder.with_topology_provider(topology_provider); } - let mut started_client = base_builder.start_base().await?; + let packet_type = self.config.packet_type; + let mut started_client = base_builder.start_base(packet_type).await?; let self_address = started_client.address.to_string(); let client_input = started_client.client_input.register_producer(); @@ -216,6 +223,7 @@ impl NymClientBuilder { client_state: Arc::new(started_client.client_state), _full_topology: None, _task_manager: started_client.task_manager, + packet_type: self.packet_type, }) } @@ -291,7 +299,7 @@ impl NymClient { let input_msgs = request .test_msgs .into_iter() - .map(|p| InputMessage::new_regular(recipient, p, lane)) + .map(|p| InputMessage::new_regular(recipient, p, lane, None)) .collect(); self.client_input.send_messages(input_msgs) @@ -311,7 +319,7 @@ impl NymClient { let lane = TransmissionLane::General; - let input_msg = InputMessage::new_regular(recipient, message, lane); + let input_msg = InputMessage::new_regular(recipient, message, lane, self.packet_type); self.client_input.send_message(input_msg) } @@ -338,7 +346,8 @@ impl NymClient { let lane = TransmissionLane::General; - let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane); + let input_msg = + InputMessage::new_anonymous(recipient, message, reply_surbs, lane, self.packet_type); self.client_input.send_message(input_msg) } @@ -356,7 +365,7 @@ impl NymClient { let lane = TransmissionLane::General; - let input_msg = InputMessage::new_reply(sender_tag, message, lane); + let input_msg = InputMessage::new_reply(sender_tag, message, lane, self.packet_type); self.client_input.send_message(input_msg) } } diff --git a/common/async-file-watcher/src/lib.rs b/common/async-file-watcher/src/lib.rs index dea2cfd335..73faaa3dfa 100644 --- a/common/async-file-watcher/src/lib.rs +++ b/common/async-file-watcher/src/lib.rs @@ -130,7 +130,7 @@ impl AsyncFileWatcher { Ok(event) => { let now = Instant::now(); if self.should_propagate(&event, now) { - self.last_received.insert(event.kind.clone(), now); + self.last_received.insert(event.kind, now); if let Err(_err) = self.event_sender.unbounded_send(event) { log::error!("the file watcher receiver has been dropped!"); } diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index f4b0e9307a..bf4803140a 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -37,6 +37,7 @@ use nym_gateway_client::{ use nym_sphinx::acknowledgements::AckKey; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::nodes::NodeIdentity; +use nym_sphinx::params::PacketType; use nym_sphinx::receiver::{ReconstructedMessage, SphinxMessageReceiver}; use nym_task::connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths}; use nym_task::{TaskClient, TaskManager}; @@ -275,6 +276,7 @@ where lane_queue_lengths: LaneQueueLengths, client_connection_rx: ConnectionCommandReceiver, shutdown: TaskClient, + packet_type: PacketType, ) { info!("Starting real traffic stream..."); @@ -290,7 +292,7 @@ where lane_queue_lengths, client_connection_rx, ) - .start_with_shutdown(shutdown); + .start_with_shutdown(shutdown, packet_type); } // buffer controlling all messages fetched from provider @@ -426,7 +428,7 @@ where Ok(()) } - // controller for sending sphinx packets to mixnet (either real traffic or cover traffic) + // controller for sending packets to mixnet (either real traffic or cover traffic) // TODO: if we want to send control messages to gateway_client, this CAN'T take the ownership // over it. Perhaps GatewayClient needs to be thread-shareable or have some channel for // requests? @@ -477,7 +479,10 @@ where self.managed_keys = ManagedKeys::load_or_generate(&mut rng, &self.key_store).await; } - pub async fn start_base(mut self) -> Result + pub async fn start_base( + mut self, + packet_type: PacketType, + ) -> Result where ::StorageError: Sync + Send, S::ReplyStore: Send + Sync, @@ -548,11 +553,11 @@ where task_manager.subscribe(), ); - // The sphinx_message_sender is the transmitter for any component generating sphinx packets + // The message_sender is the transmitter for any component generating sphinx packets // that are to be sent to the mixnet. They are used by cover traffic stream and real // traffic stream. // The MixTrafficController then sends the actual traffic - let sphinx_message_sender = + let message_sender = Self::start_mix_traffic_controller(gateway_client, task_manager.subscribe()); // Channels that the websocket listener can use to signal downstream to the real traffic @@ -574,13 +579,14 @@ where shared_topology_accessor.clone(), ack_receiver, input_receiver, - sphinx_message_sender.clone(), + message_sender.clone(), reply_storage, reply_controller_sender.clone(), reply_controller_receiver, shared_lane_queue_lengths.clone(), client_connection_rx, task_manager.subscribe(), + packet_type, ); if !self @@ -593,7 +599,7 @@ where self.managed_keys.ack_key(), self_address, shared_topology_accessor.clone(), - sphinx_message_sender, + message_sender, task_manager.subscribe(), ); } diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index f04f431151..b9029d0850 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -12,15 +12,15 @@ use nym_credential_storage::ephemeral_storage::{ }; use nym_credential_storage::storage::Storage as CredentialStorage; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use crate::client::base_client::non_wasm_helpers; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use crate::client::key_manager::persistence::OnDiskKeys; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use crate::config::{persistence::key_pathfinder::ClientKeyPathfinder, Config}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use crate::error::ClientCoreError; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] @@ -74,14 +74,14 @@ impl MixnetClientStorage for Ephemeral { } } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] pub struct OnDiskPersistent { pub(crate) key_store: OnDiskKeys, pub(crate) reply_store: fs_backend::Backend, pub(crate) credential_store: PersistentCredentialStorage, } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] impl OnDiskPersistent { pub fn new( key_store: OnDiskKeys, @@ -116,7 +116,7 @@ impl OnDiskPersistent { } } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] impl MixnetClientStorage for OnDiskPersistent { type KeyStore = OnDiskKeys; type ReplyStore = fs_backend::Backend; diff --git a/common/client-core/src/client/cover_traffic_stream.rs b/common/client-core/src/client/cover_traffic_stream.rs index 41048a1461..19f549a52f 100644 --- a/common/client-core/src/client/cover_traffic_stream.rs +++ b/common/client-core/src/client/cover_traffic_stream.rs @@ -45,7 +45,7 @@ where #[cfg(target_arch = "wasm32")] next_delay: Pin>, - /// Channel used for sending prepared sphinx packets to `MixTrafficController` that sends them + /// Channel used for sending prepared nym packets to `MixTrafficController` that sends them /// out to the network without any further delays. mix_tx: BatchMixMessageSender, @@ -194,6 +194,7 @@ impl LoopCoverTrafficStream { self.average_ack_delay, self.cover_traffic.loop_cover_traffic_average_delay, cover_traffic_packet_size, + nym_sphinx::params::PacketType::Mix, ) .expect("Somehow failed to generate a loop cover message with a valid topology"); diff --git a/common/client-core/src/client/inbound_messages.rs b/common/client-core/src/client/inbound_messages.rs index 0a1e93c435..1530073d3f 100644 --- a/common/client-core/src/client/inbound_messages.rs +++ b/common/client-core/src/client/inbound_messages.rs @@ -4,6 +4,7 @@ use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use nym_sphinx::forwarding::packet::MixPacket; +use nym_sphinx::params::PacketType; use nym_task::connections::TransmissionLane; pub type InputMessageSender = tokio::sync::mpsc::Sender; @@ -53,18 +54,49 @@ pub enum InputMessage { data: Vec, lane: TransmissionLane, }, + + MessageWrapper { + message: Box, + packet_type: PacketType, + }, } impl InputMessage { - pub fn new_premade(msgs: Vec, lane: TransmissionLane) -> Self { - InputMessage::Premade { msgs, lane } + pub fn new_premade( + msgs: Vec, + lane: TransmissionLane, + packet_type: PacketType, + ) -> Self { + let message = InputMessage::Premade { msgs, lane }; + if packet_type == PacketType::Mix { + message + } else { + InputMessage::new_wrapper(message, packet_type) + } } - pub fn new_regular(recipient: Recipient, data: Vec, lane: TransmissionLane) -> Self { - InputMessage::Regular { + pub fn new_wrapper(message: InputMessage, packet_type: PacketType) -> Self { + InputMessage::MessageWrapper { + message: Box::new(message), + packet_type, + } + } + + pub fn new_regular( + recipient: Recipient, + data: Vec, + lane: TransmissionLane, + packet_type: Option, + ) -> Self { + let message = InputMessage::Regular { recipient, data, lane, + }; + if let Some(packet_type) = packet_type { + InputMessage::new_wrapper(message, packet_type) + } else { + message } } @@ -73,12 +105,18 @@ impl InputMessage { data: Vec, reply_surbs: u32, lane: TransmissionLane, + packet_type: Option, ) -> Self { - InputMessage::Anonymous { + let message = InputMessage::Anonymous { recipient, data, reply_surbs, lane, + }; + if let Some(packet_type) = packet_type { + InputMessage::new_wrapper(message, packet_type) + } else { + message } } @@ -86,11 +124,17 @@ impl InputMessage { recipient_tag: AnonymousSenderTag, data: Vec, lane: TransmissionLane, + packet_type: Option, ) -> Self { - InputMessage::Reply { + let message = InputMessage::Reply { recipient_tag, data, lane, + }; + if let Some(packet_type) = packet_type { + InputMessage::new_wrapper(message, packet_type) + } else { + message } } @@ -100,6 +144,7 @@ impl InputMessage { | InputMessage::Anonymous { lane, .. } | InputMessage::Reply { lane, .. } | InputMessage::Premade { lane, .. } => lane, + InputMessage::MessageWrapper { message, .. } => message.lane(), } } } diff --git a/common/client-core/src/client/mix_traffic.rs b/common/client-core/src/client/mix_traffic.rs index 882b26684b..8e7f7ce2fb 100644 --- a/common/client-core/src/client/mix_traffic.rs +++ b/common/client-core/src/client/mix_traffic.rs @@ -40,15 +40,15 @@ where pub fn new( gateway_client: GatewayClient, ) -> (MixTrafficController, BatchMixMessageSender) { - let (sphinx_message_sender, sphinx_message_receiver) = + let (message_sender, message_receiver) = tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE); ( MixTrafficController { gateway_client, - mix_rx: sphinx_message_receiver, + mix_rx: message_receiver, consecutive_gateway_failure_count: 0, }, - sphinx_message_sender, + message_sender, ) } diff --git a/common/client-core/src/client/real_messages_control/acknowledgement_control/acknowledgement_listener.rs b/common/client-core/src/client/real_messages_control/acknowledgement_control/acknowledgement_listener.rs index 0034e00567..18d2959181 100644 --- a/common/client-core/src/client/real_messages_control/acknowledgement_control/acknowledgement_listener.rs +++ b/common/client-core/src/client/real_messages_control/acknowledgement_control/acknowledgement_listener.rs @@ -71,7 +71,7 @@ impl AcknowledgementListener { while !shutdown.is_shutdown() { tokio::select! { acks = self.ack_receiver.next() => match acks { - Some(acks) => self.handle_ack_receiver_item(acks).await, + Some(acks) => {self.handle_ack_receiver_item(acks).await} None => { log::trace!("AcknowledgementListener: Stopping since channel closed"); break; diff --git a/common/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs b/common/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs index 76f8918981..ab2eda1637 100644 --- a/common/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs +++ b/common/client-core/src/client/real_messages_control/acknowledgement_control/input_message_listener.rs @@ -9,6 +9,7 @@ use log::*; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use nym_sphinx::forwarding::packet::MixPacket; +use nym_sphinx::params::PacketType; use nym_task::connections::TransmissionLane; use rand::{CryptoRng, Rng}; @@ -71,10 +72,11 @@ where recipient: Recipient, content: Vec, lane: TransmissionLane, + packet_type: PacketType, ) { if let Err(err) = self .message_handler - .try_send_plain_message(recipient, content, lane) + .try_send_plain_message(recipient, content, lane, packet_type) .await { warn!("failed to send a plain message - {err}") @@ -87,10 +89,11 @@ where content: Vec, reply_surbs: u32, lane: TransmissionLane, + packet_type: PacketType, ) { if let Err(err) = self .message_handler - .try_send_message_with_reply_surbs(recipient, content, reply_surbs, lane) + .try_send_message_with_reply_surbs(recipient, content, reply_surbs, lane, packet_type) .await { warn!("failed to send a repliable message - {err}") @@ -103,14 +106,17 @@ where recipient, data, lane, - } => self.handle_plain_message(recipient, data, lane).await, + } => { + self.handle_plain_message(recipient, data, lane, PacketType::Mix) + .await + } InputMessage::Anonymous { recipient, data, reply_surbs, lane, } => { - self.handle_repliable_message(recipient, data, reply_surbs, lane) + self.handle_repliable_message(recipient, data, reply_surbs, lane, PacketType::Mix) .await } InputMessage::Reply { @@ -121,6 +127,40 @@ where self.handle_reply(recipient_tag, data, lane).await; } InputMessage::Premade { msgs, lane } => self.handle_premade_packets(msgs, lane).await, + InputMessage::MessageWrapper { + message, + packet_type, + } => match *message { + InputMessage::Regular { + recipient, + data, + lane, + } => { + self.handle_plain_message(recipient, data, lane, packet_type) + .await + } + InputMessage::Anonymous { + recipient, + data, + reply_surbs, + lane, + } => { + self.handle_repliable_message(recipient, data, reply_surbs, lane, packet_type) + .await + } + InputMessage::Reply { + recipient_tag, + data, + lane, + } => { + self.handle_reply(recipient_tag, data, lane).await; + } + InputMessage::Premade { msgs, lane } => { + self.handle_premade_packets(msgs, lane).await + } + // MessageWrappers can't be nested + InputMessage::MessageWrapper { .. } => unimplemented!(), + }, }; } diff --git a/common/client-core/src/client/real_messages_control/acknowledgement_control/mod.rs b/common/client-core/src/client/real_messages_control/acknowledgement_control/mod.rs index 1572465ed2..5f2bf6f80d 100644 --- a/common/client-core/src/client/real_messages_control/acknowledgement_control/mod.rs +++ b/common/client-core/src/client/real_messages_control/acknowledgement_control/mod.rs @@ -16,7 +16,7 @@ use futures::channel::mpsc; use log::*; use nym_gateway_client::AcknowledgementReceiver; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; -use nym_sphinx::params::PacketSize; +use nym_sphinx::params::{PacketSize, PacketType}; use nym_sphinx::{ acknowledgements::AckKey, addressing::clients::Recipient, @@ -249,7 +249,11 @@ where } } - pub(super) fn start_with_shutdown(self, shutdown: nym_task::TaskClient) { + pub(super) fn start_with_shutdown( + self, + shutdown: nym_task::TaskClient, + packet_type: PacketType, + ) { let mut acknowledgement_listener = self.acknowledgement_listener; let mut input_message_listener = self.input_message_listener; let mut retransmission_request_listener = self.retransmission_request_listener; @@ -275,7 +279,7 @@ where let shutdown_handle = shutdown.clone(); spawn_future(async move { retransmission_request_listener - .run_with_shutdown(shutdown_handle) + .run_with_shutdown(shutdown_handle, packet_type) .await; debug!("The retransmission request listener has finished execution!"); }); diff --git a/common/client-core/src/client/real_messages_control/acknowledgement_control/retransmission_request_listener.rs b/common/client-core/src/client/real_messages_control/acknowledgement_control/retransmission_request_listener.rs index 966130d1cb..abe1751284 100644 --- a/common/client-core/src/client/real_messages_control/acknowledgement_control/retransmission_request_listener.rs +++ b/common/client-core/src/client/real_messages_control/acknowledgement_control/retransmission_request_listener.rs @@ -11,9 +11,9 @@ use crate::client::real_messages_control::real_traffic_stream::RealMessage; use crate::client::replies::reply_controller::ReplyControllerSender; use futures::StreamExt; use log::*; -use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::chunking::fragment::Fragment; use nym_sphinx::preparer::PreparedFragment; +use nym_sphinx::{addressing::clients::Recipient, params::PacketType}; use nym_task::connections::TransmissionLane; use rand::{CryptoRng, Rng}; use std::sync::{Arc, Weak}; @@ -48,17 +48,20 @@ where &mut self, packet_recipient: Recipient, chunk_data: Fragment, + packet_type: PacketType, ) -> Result { debug!("retransmitting normal packet..."); + // TODO: Figure out retransmission packet type signaling self.message_handler - .try_prepare_single_chunk_for_sending(packet_recipient, chunk_data) + .try_prepare_single_chunk_for_sending(packet_recipient, chunk_data, packet_type) .await } async fn on_retransmission_request( &mut self, weak_timed_out_ack: Weak, + packet_type: PacketType, ) { let timed_out_ack = match weak_timed_out_ack.upgrade() { Some(timed_out_ack) => timed_out_ack, @@ -85,6 +88,7 @@ where self.prepare_normal_retransmission_chunk( **recipient, timed_out_ack.message_chunk.clone(), + packet_type, ) .await } @@ -140,13 +144,17 @@ where .await } - pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) { + pub(super) async fn run_with_shutdown( + &mut self, + mut shutdown: nym_task::TaskClient, + packet_type: PacketType, + ) { debug!("Started RetransmissionRequestListener with graceful shutdown support"); while !shutdown.is_shutdown() { tokio::select! { timed_out_ack = self.request_receiver.next() => match timed_out_ack { - Some(timed_out_ack) => self.on_retransmission_request(timed_out_ack).await, + Some(timed_out_ack) => self.on_retransmission_request(timed_out_ack, packet_type).await, None => { log::trace!("RetransmissionRequestListener: Stopping since channel closed"); break; diff --git a/common/client-core/src/client/real_messages_control/message_handler.rs b/common/client-core/src/client/real_messages_control/message_handler.rs index 7658016017..a92ae58e90 100644 --- a/common/client-core/src/client/real_messages_control/message_handler.rs +++ b/common/client-core/src/client/real_messages_control/message_handler.rs @@ -15,7 +15,7 @@ use nym_sphinx::anonymous_replies::requests::{AnonymousSenderTag, RepliableMessa use nym_sphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey}; use nym_sphinx::chunking::fragment::{Fragment, FragmentIdentifier}; use nym_sphinx::message::NymMessage; -use nym_sphinx::params::{PacketSize, DEFAULT_NUM_MIX_HOPS}; +use nym_sphinx::params::{PacketSize, PacketType, DEFAULT_NUM_MIX_HOPS}; use nym_sphinx::preparer::{MessagePreparer, PreparedFragment}; use nym_sphinx::Delay; use nym_task::connections::TransmissionLane; @@ -27,7 +27,7 @@ use std::time::Duration; use thiserror::Error; // TODO: move that error elsewhere since it seems to be contaminating different files -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] pub enum PreparationError { #[error(transparent)] NymTopologyError(#[from] NymTopologyError), @@ -417,9 +417,10 @@ where recipient: Recipient, message: Vec, lane: TransmissionLane, + packet_type: PacketType, ) -> Result<(), PreparationError> { let message = NymMessage::new_plain(message); - self.try_split_and_send_non_reply_message(message, recipient, lane) + self.try_split_and_send_non_reply_message(message, recipient, lane, packet_type) .await } @@ -428,7 +429,9 @@ where message: NymMessage, recipient: Recipient, lane: TransmissionLane, + packet_type: PacketType, ) -> Result<(), PreparationError> { + debug!("Sending non-reply message with packet type {packet_type}"); // TODO: I really dislike existence of this assertion, it implies code has to be re-organised debug_assert!(!matches!(message, NymMessage::Reply(_))); @@ -436,7 +439,11 @@ where let topology_permit = self.topology_access.get_read_permit().await; let topology = self.get_topology(&topology_permit)?; - let packet_size = self.optimal_packet_size(&message); + let packet_size = if packet_type == PacketType::Outfox { + PacketSize::OutfoxRegularPacket + } else { + self.optimal_packet_size(&message) + }; debug!("Using {packet_size} packets for {message}"); let fragments = self .message_preparer @@ -453,6 +460,7 @@ where topology, &self.config.ack_key, &recipient, + packet_type, )?; let real_message = RealMessage::new( @@ -476,7 +484,9 @@ where &mut self, recipient: Recipient, amount: u32, + packet_type: PacketType, ) -> Result<(), PreparationError> { + debug!("Sending additional reply SURBs with packet type {packet_type}"); let sender_tag = self.get_or_create_sender_tag(&recipient); let (reply_surbs, reply_keys) = self.generate_reply_surbs_with_keys(amount as usize).await?; @@ -490,6 +500,7 @@ where message, recipient, TransmissionLane::AdditionalReplySurbs, + packet_type, ) .await?; @@ -505,7 +516,9 @@ where message: Vec, num_reply_surbs: u32, lane: TransmissionLane, + packet_type: PacketType, ) -> Result<(), SurbWrappedPreparationError> { + debug!("Sending message with reply SURBs with packet type {packet_type}"); let sender_tag = self.get_or_create_sender_tag(&recipient); let (reply_surbs, reply_keys) = self .generate_reply_surbs_with_keys(num_reply_surbs as usize) @@ -514,7 +527,7 @@ where let message = NymMessage::new_repliable(RepliableMessage::new_data(message, sender_tag, reply_surbs)); - self.try_split_and_send_non_reply_message(message, recipient, lane) + self.try_split_and_send_non_reply_message(message, recipient, lane, packet_type) .await?; log::trace!("storing {} reply keys", reply_keys.len()); @@ -527,13 +540,21 @@ where &mut self, recipient: Recipient, chunk: Fragment, + packet_type: PacketType, ) -> Result { + debug!("Sending single chunk with packet type {packet_type}"); let topology_permit = self.topology_access.get_read_permit().await; let topology = self.get_topology(&topology_permit)?; let prepared_fragment = self .message_preparer - .prepare_chunk_for_sending(chunk, topology, &self.config.ack_key, &recipient) + .prepare_chunk_for_sending( + chunk, + topology, + &self.config.ack_key, + &recipient, + packet_type, + ) .unwrap(); Ok(prepared_fragment) @@ -569,6 +590,7 @@ where topology, &self.config.ack_key, reply_surb, + PacketType::Mix, ) .unwrap() }) @@ -588,7 +610,13 @@ where let prepared_fragment = self .message_preparer - .prepare_reply_chunk_for_sending(chunk, topology, &self.config.ack_key, reply_surb) + .prepare_reply_chunk_for_sending( + chunk, + topology, + &self.config.ack_key, + reply_surb, + PacketType::Mix, + ) .unwrap(); Ok(prepared_fragment) diff --git a/common/client-core/src/client/real_messages_control/mod.rs b/common/client-core/src/client/real_messages_control/mod.rs index bfb3c0e1fc..32c913006d 100644 --- a/common/client-core/src/client/real_messages_control/mod.rs +++ b/common/client-core/src/client/real_messages_control/mod.rs @@ -26,6 +26,7 @@ use log::*; use nym_gateway_client::AcknowledgementReceiver; use nym_sphinx::acknowledgements::AckKey; use nym_sphinx::addressing::clients::Recipient; +use nym_sphinx::params::PacketType; use nym_task::connections::{ConnectionCommandReceiver, LaneQueueLengths}; use rand::{rngs::OsRng, CryptoRng, Rng}; use std::sync::Arc; @@ -207,7 +208,7 @@ impl RealMessagesController { } } - pub fn start_with_shutdown(self, shutdown: nym_task::TaskClient) { + pub fn start_with_shutdown(self, shutdown: nym_task::TaskClient, packet_type: PacketType) { let mut out_queue_control = self.out_queue_control; let ack_control = self.ack_control; let mut reply_control = self.reply_control; @@ -223,6 +224,6 @@ impl RealMessagesController { debug!("The reply controller has finished execution!"); }); - ack_control.start_with_shutdown(shutdown); + ack_control.start_with_shutdown(shutdown, packet_type); } } diff --git a/common/client-core/src/client/real_messages_control/real_traffic_stream.rs b/common/client-core/src/client/real_messages_control/real_traffic_stream.rs index c7e5c80dfe..c0f9cce6aa 100644 --- a/common/client-core/src/client/real_messages_control/real_traffic_stream.rs +++ b/common/client-core/src/client/real_messages_control/real_traffic_stream.rs @@ -92,7 +92,7 @@ where // messages. sending_delay_controller: SendingDelayController, - /// Channel used for sending prepared sphinx packets to `MixTrafficController` that sends them + /// Channel used for sending prepared packets to `MixTrafficController` that sends them /// out to the network without any further delays. mix_tx: BatchMixMessageSender, @@ -136,7 +136,7 @@ impl From for RealMessage { impl RealMessage { pub(crate) fn packet_size(&self) -> usize { - self.mix_packet.sphinx_packet().len() + self.mix_packet.packet().len() } pub(crate) fn new(mix_packet: MixPacket, fragment_id: Option) -> Self { @@ -247,6 +247,7 @@ where self.config.average_ack_delay, self.config.traffic.average_packet_delay, cover_traffic_packet_size, + self.config.traffic.packet_type.unwrap_or_default(), ) .expect( "Somehow failed to generate a loop cover message with a valid topology", @@ -386,7 +387,7 @@ where // On every iteration we get new messages from upstream. Given that these come bunched // in `Vec`, this ensures that on average we will fetch messages faster than we can - // send, which is a condition for being able to multiplex sphinx packets from multiple + // send, which is a condition for being able to multiplex packets from multiple // data streams. match Pin::new(&mut self.real_receiver).poll_recv(cx) { // in the case our real message channel stream was closed, we should also indicate we are closed diff --git a/common/client-core/src/client/replies/reply_controller/mod.rs b/common/client-core/src/client/replies/reply_controller/mod.rs index 21e1f5a9d1..0e5a5a0ae9 100644 --- a/common/client-core/src/client/replies/reply_controller/mod.rs +++ b/common/client-core/src/client/replies/reply_controller/mod.rs @@ -512,7 +512,11 @@ where let to_send = min(remaining, 100); if let Err(err) = self .message_handler - .try_send_additional_reply_surbs(recipient, to_send) + .try_send_additional_reply_surbs( + recipient, + to_send, + nym_sphinx::params::PacketType::Mix, + ) .await { warn!("failed to send additional surbs to {recipient} - {err}"); diff --git a/common/client-core/src/client/transmission_buffer.rs b/common/client-core/src/client/transmission_buffer.rs index 5423cc57a6..65c0e23976 100644 --- a/common/client-core/src/client/transmission_buffer.rs +++ b/common/client-core/src/client/transmission_buffer.rs @@ -28,7 +28,7 @@ impl SizedData for RealMessage { impl SizedData for Fragment { fn data_size(&self) -> usize { - // note that raw `Fragment` is smaller than sphinx packet payload + // note that raw `Fragment` is smaller than packet payload // as it doesn't include surb-ack or the [shared] key materials self.payload_size() } diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index 546be9a2db..bd919d3a37 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -4,7 +4,7 @@ use nym_config::defaults::NymNetworkDetails; use nym_config::{NymConfig, OptionalSet, CRED_DB_FILE_NAME}; use nym_crypto::asymmetric::identity; -use nym_sphinx::params::PacketSize; +use nym_sphinx::params::{PacketSize, PacketType}; use serde::{Deserialize, Serialize}; use std::marker::PhantomData; use std::path::{Path, PathBuf}; @@ -259,6 +259,11 @@ impl Config { self } + pub fn with_packet_type(mut self, packet_type: PacketType) -> Self { + self.client.packet_type = Some(packet_type); + self + } + pub fn set_high_default_traffic_volume(&mut self) { self.debug.traffic.average_packet_delay = Duration::from_millis(10); // basically don't really send cover messages @@ -446,6 +451,10 @@ impl Config { pub fn get_maximum_reply_key_age(&self) -> Duration { self.debug.reply_surbs.maximum_reply_key_age } + + pub fn get_packet_type(&self) -> PacketType { + self.client.packet_type.unwrap_or(PacketType::Mix) + } } impl Default for Config { @@ -568,6 +577,8 @@ pub struct Client { #[serde(skip)] pub super_struct: PhantomData, + + pub packet_type: Option, } impl Default for Client { @@ -606,6 +617,7 @@ impl Default for Client { reply_surb_database_path: Default::default(), nym_root_directory: T::default_root_directory(), super_struct: Default::default(), + packet_type: Default::default(), } } } @@ -677,6 +689,8 @@ pub struct Traffic { /// Note that its use decreases overall anonymity. /// Do not set it it unless you understand the consequences of that change. pub secondary_packet_size: Option, + + pub packet_type: Option, } impl Traffic { @@ -700,6 +714,7 @@ impl Default for Traffic { disable_main_poisson_packet_distribution: false, primary_packet_size: PacketSize::RegularPacket, secondary_packet_size: None, + packet_type: None, } } } diff --git a/common/client-core/src/config/old_config_v1_1_13.rs b/common/client-core/src/config/old_config_v1_1_13.rs index ee01616564..9c06f885b0 100644 --- a/common/client-core/src/config/old_config_v1_1_13.rs +++ b/common/client-core/src/config/old_config_v1_1_13.rs @@ -125,6 +125,7 @@ impl From for DebugConfig { .disable_main_poisson_packet_distribution, primary_packet_size: PacketSize::RegularPacket, secondary_packet_size: value.use_extended_packet_size.map(Into::into), + packet_type: None, }, cover_traffic: CoverTraffic { loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay, @@ -210,8 +211,8 @@ impl From> for Config { database_path: value.client.database_path, reply_surb_database_path: value.client.reply_surb_database_path, nym_root_directory: value.client.nym_root_directory, - super_struct: PhantomData, + packet_type: Some(nym_sphinx::params::PacketType::Mix), }, logging: value.logging, debug: value.debug.into(), diff --git a/common/client-core/src/config/persistence/key_pathfinder.rs b/common/client-core/src/config/persistence/key_pathfinder.rs index fc2db82522..135b8f61da 100644 --- a/common/client-core/src/config/persistence/key_pathfinder.rs +++ b/common/client-core/src/config/persistence/key_pathfinder.rs @@ -40,11 +40,17 @@ impl ClientKeyPathfinder { } pub fn identity_key_pair_path(&self) -> nym_pemstore::KeyPairPath { - nym_pemstore::KeyPairPath::new(self.private_identity_key(), self.public_identity_key()) + nym_pemstore::KeyPairPath::new( + self.private_identity_key().to_path_buf(), + self.public_identity_key().to_path_buf(), + ) } pub fn encryption_key_pair_path(&self) -> nym_pemstore::KeyPairPath { - nym_pemstore::KeyPairPath::new(self.private_encryption_key(), self.public_encryption_key()) + nym_pemstore::KeyPairPath::new( + self.private_encryption_key().to_path_buf(), + self.public_encryption_key().to_path_buf(), + ) } pub fn any_file_exists(&self) -> bool { diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index c964dbe2d2..2baf5718c0 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -571,7 +571,7 @@ impl GatewayClient { fn estimate_required_bandwidth(&self, packets: &[MixPacket]) -> i64 { packets .iter() - .map(|packet| packet.sphinx_packet().len()) + .map(|packet| packet.packet().len()) .sum::() as i64 } @@ -579,6 +579,8 @@ impl GatewayClient { &mut self, packets: Vec, ) -> Result<(), GatewayClientError> { + debug!("Sending {} mix packets", packets.len()); + if !self.authenticated { return Err(GatewayClientError::NotAuthenticated); } @@ -623,9 +625,10 @@ impl GatewayClient { ) -> Result<(), GatewayClientError> { if let Err(err) = self.send_websocket_message_without_response(msg).await { if err.is_closed_connection() && self.should_reconnect_on_failure { - info!("Going to attempt a reconnection"); + debug!("Going to attempt a reconnection"); self.attempt_reconnection().await } else { + warn!("{err}"); Err(err) } } else { @@ -652,9 +655,9 @@ impl GatewayClient { if !self.authenticated { return Err(GatewayClientError::NotAuthenticated); } - if (mix_packet.sphinx_packet().len() as i64) > self.bandwidth_remaining { + if (mix_packet.packet().len() as i64) > self.bandwidth_remaining { return Err(GatewayClientError::NotEnoughBandwidth( - mix_packet.sphinx_packet().len() as i64, + mix_packet.packet().len() as i64, self.bandwidth_remaining, )); } diff --git a/common/client-libs/gateway-client/src/packet_router.rs b/common/client-libs/gateway-client/src/packet_router.rs index c758abcc19..0b4a99f1c2 100644 --- a/common/client-libs/gateway-client/src/packet_router.rs +++ b/common/client-libs/gateway-client/src/packet_router.rs @@ -50,10 +50,15 @@ impl PacketRouter { let ack_overhead = PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN; for received_packet in unwrapped_packets { - if received_packet.len() == PacketSize::AckPacket.plaintext_size() { + if received_packet.len() == PacketSize::AckPacket.plaintext_size() + || received_packet.len() == PacketSize::OutfoxAckPacket.plaintext_size() + { received_acks.push(received_packet); } else if received_packet.len() == PacketSize::RegularPacket.plaintext_size() - ack_overhead + || received_packet.len() + == PacketSize::OutfoxRegularPacket.plaintext_size() - ack_overhead + || received_packet.len() == PacketSize::OutfoxRegularPacket.size() - 6 { trace!("routing regular packet"); received_messages.push(received_packet); diff --git a/common/client-libs/mixnet-client/src/client.rs b/common/client-libs/mixnet-client/src/client.rs index 62e37bca90..4da308144f 100644 --- a/common/client-libs/mixnet-client/src/client.rs +++ b/common/client-libs/mixnet-client/src/client.rs @@ -4,10 +4,11 @@ use futures::channel::mpsc; use futures::StreamExt; use log::*; -use nym_sphinx::framing::codec::SphinxCodec; -use nym_sphinx::framing::packet::FramedSphinxPacket; -use nym_sphinx::params::PacketMode; -use nym_sphinx::{addressing::nodes::NymNodeRoutingAddress, SphinxPacket}; +use nym_sphinx::addressing::nodes::NymNodeRoutingAddress; +use nym_sphinx::framing::codec::NymCodec; +use nym_sphinx::framing::packet::FramedNymPacket; +use nym_sphinx::params::PacketType; +use nym_sphinx::NymPacket; use std::collections::HashMap; use std::io; use std::net::SocketAddr; @@ -50,8 +51,8 @@ pub trait SendWithoutResponse { fn send_without_response( &mut self, address: NymNodeRoutingAddress, - packet: SphinxPacket, - packet_mode: PacketMode, + packet: NymPacket, + packet_type: PacketType, ) -> io::Result<()>; } @@ -61,12 +62,12 @@ pub struct Client { } struct ConnectionSender { - channel: mpsc::Sender, + channel: mpsc::Sender, current_reconnection_attempt: Arc, } impl ConnectionSender { - fn new(channel: mpsc::Sender) -> Self { + fn new(channel: mpsc::Sender) -> Self { ConnectionSender { channel, current_reconnection_attempt: Arc::new(AtomicU32::new(0)), @@ -84,7 +85,7 @@ impl Client { async fn manage_connection( address: SocketAddr, - receiver: mpsc::Receiver, + receiver: mpsc::Receiver, connection_timeout: Duration, current_reconnection: &AtomicU32, ) { @@ -96,7 +97,7 @@ impl Client { debug!("Managed to establish connection to {}", address); // if we managed to connect, reset the reconnection count (whatever it might have been) current_reconnection.store(0, Ordering::Release); - Framed::new(stream, SphinxCodec) + Framed::new(stream, NymCodec) } Err(err) => { debug!( @@ -148,11 +149,7 @@ impl Client { } } - fn make_connection( - &mut self, - address: NymNodeRoutingAddress, - pending_packet: FramedSphinxPacket, - ) { + fn make_connection(&mut self, address: NymNodeRoutingAddress, pending_packet: FramedNymPacket) { let (mut sender, receiver) = mpsc::channel(self.config.maximum_connection_buffer_size); // this CAN'T fail because we just created the channel which has a non-zero capacity @@ -200,12 +197,12 @@ impl SendWithoutResponse for Client { fn send_without_response( &mut self, address: NymNodeRoutingAddress, - packet: SphinxPacket, - packet_mode: PacketMode, + packet: NymPacket, + packet_type: PacketType, ) -> io::Result<()> { trace!("Sending packet to {:?}", address); let framed_packet = - FramedSphinxPacket::new(packet, packet_mode, self.config.use_legacy_version); + FramedNymPacket::new(packet, packet_type, self.config.use_legacy_version); if let Some(sender) = self.conn_new.get_mut(&address) { if let Err(err) = sender.channel.try_send(framed_packet) { diff --git a/common/client-libs/mixnet-client/src/forwarder.rs b/common/client-libs/mixnet-client/src/forwarder.rs index cefae1fc30..8bbf5a47f6 100644 --- a/common/client-libs/mixnet-client/src/forwarder.rs +++ b/common/client-libs/mixnet-client/src/forwarder.rs @@ -59,14 +59,14 @@ impl PacketForwarder { trace!("Going to forward packet to {:?}", mix_packet.next_hop()); let next_hop = mix_packet.next_hop(); - let packet_mode = mix_packet.packet_mode(); - let sphinx_packet = mix_packet.into_sphinx_packet(); + let packet_type = mix_packet.packet_type(); + let packet = mix_packet.into_packet(); // we don't care about responses, we just want to fire packets // as quickly as possible if let Err(err) = self.mixnet_client - .send_without_response(next_hop, sphinx_packet, packet_mode) + .send_without_response(next_hop, packet, packet_type) { debug!("failed to forward the packet - {err}") } diff --git a/common/mixnode-common/src/packet_processor/error.rs b/common/mixnode-common/src/packet_processor/error.rs index 99d3a2d2f2..9c0c1e5ab0 100644 --- a/common/mixnode-common/src/packet_processor/error.rs +++ b/common/mixnode-common/src/packet_processor/error.rs @@ -3,12 +3,15 @@ use nym_sphinx_acknowledgements::surb_ack::SurbAckRecoveryError; use nym_sphinx_addressing::nodes::NymNodeRoutingAddressError; -use nym_sphinx_types::Error as SphinxError; +use nym_sphinx_types::{NymPacketError, SphinxError}; use thiserror::Error; #[derive(Error, Debug)] pub enum MixProcessingError { #[error("failed to process received packet: {0}")] + NymPacketProcessingError(#[from] NymPacketError), + + #[error("failed to process received sphinx packet: {0}")] SphinxProcessingError(#[from] SphinxError), #[error("the forward hop address was malformed: {0}")] diff --git a/common/mixnode-common/src/packet_processor/processor.rs b/common/mixnode-common/src/packet_processor/processor.rs index 98847d8983..8acbc9d90b 100644 --- a/common/mixnode-common/src/packet_processor/processor.rs +++ b/common/mixnode-common/src/packet_processor/processor.rs @@ -7,11 +7,11 @@ use log::*; use nym_sphinx_acknowledgements::surb_ack::SurbAck; use nym_sphinx_addressing::nodes::NymNodeRoutingAddress; use nym_sphinx_forwarding::packet::MixPacket; -use nym_sphinx_framing::packet::FramedSphinxPacket; -use nym_sphinx_params::{PacketMode, PacketSize}; +use nym_sphinx_framing::packet::FramedNymPacket; +use nym_sphinx_params::{PacketSize, PacketType}; use nym_sphinx_types::{ - Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, Payload, PrivateKey, - ProcessedPacket, SphinxPacket, + Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, NymProcessedPacket, + PrivateKey, ProcessedPacket, }; use std::convert::TryFrom; use std::sync::Arc; @@ -53,14 +53,14 @@ impl SphinxPacketProcessor { feature = "cpucycles", instrument(skip(self, packet), fields(cpucycles)) )] - fn perform_initial_sphinx_packet_processing( + fn perform_initial_packet_processing( &self, - packet: SphinxPacket, - ) -> Result { + packet: NymPacket, + ) -> Result { measure!({ packet.process(&self.sphinx_key).map_err(|err| { - debug!("Failed to unwrap Sphinx packet: {err}"); - MixProcessingError::SphinxProcessingError(err) + debug!("Failed to unwrap NymPacket packet: {err}"); + MixProcessingError::NymPacketProcessingError(err) }) }) } @@ -72,17 +72,12 @@ impl SphinxPacketProcessor { )] fn perform_initial_unwrapping( &self, - received: FramedSphinxPacket, - ) -> Result { + received: FramedNymPacket, + ) -> Result { measure!({ - let packet_mode = received.packet_mode(); - let sphinx_packet = received.into_inner(); + let packet = received.into_inner(); - if packet_mode.is_old_vpn() { - return Err(MixProcessingError::ReceivedOldTypeVpnPacket); - } - - self.perform_initial_sphinx_packet_processing(sphinx_packet) + self.perform_initial_packet_processing(packet) }) } @@ -90,14 +85,14 @@ impl SphinxPacketProcessor { /// and packs all the data in a way that can be easily sent to the next hop. fn process_forward_hop( &self, - packet: SphinxPacket, + packet: NymPacket, forward_address: NodeAddressBytes, delay: SphinxDelay, - packet_mode: PacketMode, + packet_type: PacketType, ) -> Result { let next_hop_address = NymNodeRoutingAddress::try_from(forward_address)?; - let mix_packet = MixPacket::new(next_hop_address, packet, packet_mode); + let mix_packet = MixPacket::new(next_hop_address, packet, packet_type); Ok(MixProcessingResult::ForwardHop(mix_packet, Some(delay))) } @@ -106,14 +101,17 @@ impl SphinxPacketProcessor { fn split_hop_data_into_ack_and_message( &self, mut extracted_data: Vec, + packet_type: PacketType, ) -> Result<(Vec, Vec), MixProcessingError> { + let ack_len = SurbAck::len(Some(packet_type)); + // in theory it's impossible for this to fail since it managed to go into correct `match` // branch at the caller - if extracted_data.len() < SurbAck::len() { + if extracted_data.len() < ack_len { return Err(MixProcessingError::NoSurbAckInFinalHop); } - let message = extracted_data.split_off(SurbAck::len()); + let message = extracted_data.split_off(ack_len); let ack_data = extracted_data; Ok((ack_data, message)) } @@ -124,21 +122,30 @@ impl SphinxPacketProcessor { &self, data: Vec, packet_size: PacketSize, - packet_mode: PacketMode, + packet_type: PacketType, ) -> Result<(Option, Vec), MixProcessingError> { match packet_size { - PacketSize::AckPacket => { + PacketSize::AckPacket | PacketSize::OutfoxAckPacket => { trace!("received an ack packet!"); Ok((None, data)) } PacketSize::RegularPacket | PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 - | PacketSize::ExtendedPacket32 => { + | PacketSize::ExtendedPacket32 + | PacketSize::OutfoxRegularPacket => { trace!("received a normal packet!"); - let (ack_data, message) = self.split_hop_data_into_ack_and_message(data)?; - let (ack_first_hop, ack_packet) = SurbAck::try_recover_first_hop_packet(&ack_data)?; - let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_mode); + let (ack_data, message) = + self.split_hop_data_into_ack_and_message(data, packet_type)?; + let (ack_first_hop, ack_packet) = + match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) { + Ok((first_hop, packet)) => (first_hop, packet), + Err(err) => { + debug!("Failed to recover first hop from ack data: {err}"); + return Err(err.into()); + } + }; + let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_type); Ok((Some(forward_ack), message)) } } @@ -150,14 +157,12 @@ impl SphinxPacketProcessor { fn process_final_hop( &self, destination: DestinationAddressBytes, - payload: Payload, + payload: Vec, packet_size: PacketSize, - packet_mode: PacketMode, + packet_type: PacketType, ) -> Result { - let packet_message = payload.recover_plaintext()?; - let (forward_ack, message) = - self.split_into_ack_and_message(packet_message, packet_size, packet_mode)?; + self.split_into_ack_and_message(payload, packet_size, packet_type)?; Ok(MixProcessingResult::FinalHop(ProcessedFinalHop { destination, @@ -170,18 +175,48 @@ impl SphinxPacketProcessor { /// or a final hop. fn perform_final_processing( &self, - packet: ProcessedPacket, + packet: NymProcessedPacket, packet_size: PacketSize, - packet_mode: PacketMode, + packet_type: PacketType, ) -> Result { match packet { - ProcessedPacket::ForwardHop(packet, address, delay) => { - self.process_forward_hop(*packet, address, delay, packet_mode) + NymProcessedPacket::Sphinx(packet) => { + match packet { + ProcessedPacket::ForwardHop(packet, address, delay) => self + .process_forward_hop( + NymPacket::Sphinx(*packet), + address, + delay, + packet_type, + ), + // right now there's no use for the surb_id included in the header - probably it should get removed from the + // sphinx all together? + ProcessedPacket::FinalHop(destination, _, payload) => self.process_final_hop( + destination, + payload.recover_plaintext()?, + packet_size, + packet_type, + ), + } } - // right now there's no use for the surb_id included in the header - probably it should get removed from the - // sphinx all together? - ProcessedPacket::FinalHop(destination, _, payload) => { - self.process_final_hop(destination, payload, packet_size, packet_mode) + NymProcessedPacket::Outfox(packet) => { + let next_address = *packet.next_address(); + let packet = packet.into_packet(); + if packet.is_final_hop() { + self.process_final_hop( + DestinationAddressBytes::from_bytes(next_address), + packet.recover_plaintext().to_vec(), + packet_size, + packet_type, + ) + } else { + let mix_packet = MixPacket::new( + NymNodeRoutingAddress::try_from_bytes(&next_address)?, + NymPacket::Outfox(packet), + PacketType::Outfox, + ); + Ok(MixProcessingResult::ForwardHop(mix_packet, None)) + } } } } @@ -192,19 +227,19 @@ impl SphinxPacketProcessor { )] pub fn process_received( &self, - received: FramedSphinxPacket, + received: FramedNymPacket, ) -> Result { // explicit packet size will help to correctly parse final hop measure!({ let packet_size = received.packet_size(); - let packet_mode = received.packet_mode(); + let packet_type = received.packet_type(); // unwrap the sphinx packet and if possible and appropriate, cache keys let processed_packet = self.perform_initial_unwrapping(received)?; // for forward packets, extract next hop and set delay (but do NOT delay here) // for final packets, extract SURBAck - self.perform_final_processing(processed_packet, packet_size, packet_mode) + self.perform_final_processing(processed_packet, packet_size, packet_type) }) } } @@ -226,31 +261,71 @@ mod tests { let short_data = vec![42u8]; assert!(processor - .split_hop_data_into_ack_and_message(short_data) + .split_hop_data_into_ack_and_message(short_data, PacketType::Mix) .is_err()); - let sufficient_data = vec![42u8; SurbAck::len()]; + let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Mix))]; let (ack, data) = processor - .split_hop_data_into_ack_and_message(sufficient_data.clone()) + .split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Mix) .unwrap(); assert_eq!(sufficient_data, ack); assert!(data.is_empty()); - let long_data = vec![42u8; SurbAck::len() * 5]; + let long_data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) * 5]; let (ack, data) = processor - .split_hop_data_into_ack_and_message(long_data) + .split_hop_data_into_ack_and_message(long_data, PacketType::Mix) .unwrap(); - assert_eq!(ack.len(), SurbAck::len()); - assert_eq!(data.len(), SurbAck::len() * 4) + assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Mix))); + assert_eq!(data.len(), SurbAck::len(Some(PacketType::Mix)) * 4) + } + + #[tokio::test] + async fn splitting_hop_data_works_for_sufficiently_long_payload_outfox() { + let processor = fixture(); + + let short_data = vec![42u8]; + assert!(processor + .split_hop_data_into_ack_and_message(short_data, PacketType::Outfox) + .is_err()); + + let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox))]; + let (ack, data) = processor + .split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Outfox) + .unwrap(); + assert_eq!(sufficient_data, ack); + assert!(data.is_empty()); + + let long_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) * 5]; + let (ack, data) = processor + .split_hop_data_into_ack_and_message(long_data, PacketType::Outfox) + .unwrap(); + assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Outfox))); + assert_eq!(data.len(), SurbAck::len(Some(PacketType::Outfox)) * 4) } #[tokio::test] async fn splitting_into_ack_and_message_returns_whole_data_for_ack() { let processor = fixture(); - let data = vec![42u8; SurbAck::len() + 10]; + let data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) + 10]; let (ack, message) = processor - .split_into_ack_and_message(data.clone(), PacketSize::AckPacket, Default::default()) + .split_into_ack_and_message(data.clone(), PacketSize::AckPacket, PacketType::Mix) + .unwrap(); + assert!(ack.is_none()); + assert_eq!(data, message) + } + + #[tokio::test] + async fn splitting_into_ack_and_message_returns_whole_data_for_ack_outfox() { + let processor = fixture(); + + let data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) + 10]; + let (ack, message) = processor + .split_into_ack_and_message( + data.clone(), + PacketSize::OutfoxAckPacket, + PacketType::Outfox, + ) .unwrap(); assert!(ack.is_none()); assert_eq!(data, message) diff --git a/common/node-tester-utils/Cargo.toml b/common/node-tester-utils/Cargo.toml index eea8d1b21b..39a93d4a9f 100644 --- a/common/node-tester-utils/Cargo.toml +++ b/common/node-tester-utils/Cargo.toml @@ -17,6 +17,7 @@ tokio = { workspace = true, features = ["macros"]} nym-crypto = { path = "../crypto", features = ["asymmetric"] } nym-task = { path = "../task" } nym-topology = { path = "../topology" } +nym-sphinx-params = { path = "../nymsphinx/params" } # TODO: do we need the whole nymsphinx? nym-sphinx = { path = "../nymsphinx" } diff --git a/common/node-tester-utils/src/tester.rs b/common/node-tester-utils/src/tester.rs index 052f919ffe..0b807c54f2 100644 --- a/common/node-tester-utils/src/tester.rs +++ b/common/node-tester-utils/src/tester.rs @@ -10,6 +10,7 @@ use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::message::NymMessage; use nym_sphinx::params::{PacketSize, DEFAULT_NUM_MIX_HOPS}; use nym_sphinx::preparer::{FragmentPreparer, PreparedFragment}; +use nym_sphinx_params::PacketType; use nym_topology::{gateway, mix, NymTopology}; use rand::{CryptoRng, Rng}; use serde::Serialize; @@ -243,7 +244,14 @@ where // TODO: can we avoid this arc clone? let ack_key = Arc::clone(&self.ack_key); - Ok(self.prepare_chunk_for_sending(fragment, topology, &ack_key, &address, &address)?) + Ok(self.prepare_chunk_for_sending( + fragment, + topology, + &ack_key, + &address, + &address, + PacketType::Mix, + )?) } pub fn create_test_packet( diff --git a/common/nymsphinx/Cargo.toml b/common/nymsphinx/Cargo.toml index d229adfa75..dba8e6f265 100644 --- a/common/nymsphinx/Cargo.toml +++ b/common/nymsphinx/Cargo.toml @@ -28,9 +28,6 @@ nym-sphinx-types = { path = "types" } nym-crypto = { path = "../crypto", version = "0.3.0" } nym-topology = { path = "../topology" } -# outfox -nym-outfox = { path = "../../nym-outfox" } - [dev-dependencies] nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" } nym-crypto = { path = "../crypto", version = "0.3.0", features = ["asymmetric"] } diff --git a/common/nymsphinx/acknowledgements/src/identifier.rs b/common/nymsphinx/acknowledgements/src/identifier.rs index 9f6ffb49be..aab5a96146 100644 --- a/common/nymsphinx/acknowledgements/src/identifier.rs +++ b/common/nymsphinx/acknowledgements/src/identifier.rs @@ -3,9 +3,7 @@ use crate::AckKey; use nym_crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, IvSizeUser}; -use nym_sphinx_params::{ - packet_sizes::PacketSize, AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN, -}; +use nym_sphinx_params::{AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN}; use rand::{CryptoRng, RngCore}; // TODO: should those functions even exist in this file? @@ -26,12 +24,6 @@ pub fn recover_identifier( key: &AckKey, iv_id_ciphertext: &[u8], ) -> Option { - // The content of an 'ACK' packet consists of AckEncryptionAlgorithm::IV followed by - // serialized FragmentIdentifier - if iv_id_ciphertext.len() != PacketSize::AckPacket.plaintext_size() { - return None; - } - let iv_size = AckEncryptionAlgorithm::iv_size(); let iv = iv_from_slice::(&iv_id_ciphertext[..iv_size]); diff --git a/common/nymsphinx/acknowledgements/src/surb_ack.rs b/common/nymsphinx/acknowledgements/src/surb_ack.rs index 5df36e1f0b..b303aa2e8b 100644 --- a/common/nymsphinx/acknowledgements/src/surb_ack.rs +++ b/common/nymsphinx/acknowledgements/src/surb_ack.rs @@ -8,21 +8,18 @@ use nym_sphinx_addressing::nodes::{ NymNodeRoutingAddress, NymNodeRoutingAddressError, MAX_NODE_ADDRESS_UNPADDED_LEN, }; use nym_sphinx_params::packet_sizes::PacketSize; -use nym_sphinx_params::DEFAULT_NUM_MIX_HOPS; -use nym_sphinx_types::builder::SphinxPacketBuilder; -use nym_sphinx_types::Error as SphinxError; -use nym_sphinx_types::{ - delays::{self, Delay}, - SphinxPacket, -}; +use nym_sphinx_params::{PacketType, DEFAULT_NUM_MIX_HOPS}; +use nym_sphinx_types::delays::{self, Delay}; +use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE}; use nym_topology::{NymTopology, NymTopologyError}; use rand::{CryptoRng, RngCore}; use std::convert::TryFrom; use std::time; use thiserror::Error; +#[derive(Debug)] pub struct SurbAck { - surb_ack_packet: SphinxPacket, + surb_ack_packet: NymPacket, first_hop_address: NymNodeRoutingAddress, expected_total_delay: Delay, } @@ -35,8 +32,8 @@ pub enum SurbAckRecoveryError { #[error("could not extract first hop address information - {0}")] InvalidAddress(#[from] NymNodeRoutingAddressError), - #[error("the contained sphinx packet was not correctly formed - {0}")] - InvalidSphinxPacket(#[from] SphinxError), + #[error("packet: {0}")] + NymPacket(#[from] NymPacketError), } impl SurbAck { @@ -47,6 +44,7 @@ impl SurbAck { marshaled_fragment_id: [u8; 5], average_delay: time::Duration, topology: &NymTopology, + packet_type: PacketType, ) -> Result where R: RngCore + CryptoRng, @@ -57,11 +55,34 @@ impl SurbAck { let destination = recipient.as_sphinx_destination(); let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id); + let packet_size = match packet_type { + PacketType::Outfox => surb_ack_payload.len().max(MIN_PACKET_SIZE), + PacketType::Mix => PacketSize::AckPacket.payload_size(), + PacketType::Vpn => PacketSize::AckPacket.payload_size(), + }; - let surb_ack_packet = SphinxPacketBuilder::new() - .with_payload_size(PacketSize::AckPacket.payload_size()) - .build_packet(surb_ack_payload, &route, &destination, &delays) - .unwrap(); + let surb_ack_packet = match packet_type { + PacketType::Outfox => NymPacket::outfox_build( + surb_ack_payload, + route.as_slice(), + &destination, + Some(packet_size), + )?, + PacketType::Mix => NymPacket::sphinx_build( + packet_size, + surb_ack_payload, + &route, + &destination, + &delays, + )?, + PacketType::Vpn => NymPacket::sphinx_build( + packet_size, + surb_ack_payload, + &route, + &destination, + &delays, + )?, + }; // in our case, the last hop is a gateway that does NOT do any delays let expected_total_delay = delays.iter().take(delays.len() - 1).sum(); @@ -75,45 +96,50 @@ impl SurbAck { }) } - pub fn len() -> usize { + pub fn len(packet_type: Option) -> usize { // TODO: this will be variable once/if we decide to introduce optimization described // in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size() - PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN + let packet_type = packet_type.unwrap_or(PacketType::Mix); + match packet_type { + PacketType::Outfox => { + PacketSize::OutfoxAckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN + } + PacketType::Mix => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN, + PacketType::Vpn => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN, + } } pub fn expected_total_delay(&self) -> Delay { self.expected_total_delay } - pub fn prepare_for_sending(self) -> (Delay, Vec) { + pub fn prepare_for_sending(self) -> Result<(Delay, Vec), SurbAckRecoveryError> { // SURB_FIRST_HOP || SURB_ACK let surb_bytes: Vec<_> = self .first_hop_address .as_zero_padded_bytes(MAX_NODE_ADDRESS_UNPADDED_LEN) .into_iter() - .chain(self.surb_ack_packet.to_bytes().into_iter()) + .chain(self.surb_ack_packet.to_bytes()?.into_iter()) .collect(); - (self.expected_total_delay, surb_bytes) + Ok((self.expected_total_delay, surb_bytes)) } // partial reciprocal of `prepare_for_sending` performed by the gateway pub fn try_recover_first_hop_packet( b: &[u8], - ) -> Result<(NymNodeRoutingAddress, SphinxPacket), SurbAckRecoveryError> { - if b.len() != Self::len() { - Err(SurbAckRecoveryError::InvalidPacketSize { - received: b.len(), - expected: Self::len(), - }) - } else { - let address = NymNodeRoutingAddress::try_from_bytes(b)?; + packet_type: PacketType, + ) -> Result<(NymNodeRoutingAddress, NymPacket), SurbAckRecoveryError> { + let address = NymNodeRoutingAddress::try_from_bytes(b)?; - // TODO: this will be variable once/if we decide to introduce optimization described - // in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size() - let address_offset = MAX_NODE_ADDRESS_UNPADDED_LEN; - let packet = SphinxPacket::from_bytes(&b[address_offset..])?; + // TODO: this will be variable once/if we decide to introduce optimization described + // in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size() + let address_offset = MAX_NODE_ADDRESS_UNPADDED_LEN; + let packet = match packet_type { + PacketType::Outfox => NymPacket::outfox_from_bytes(&b[address_offset..])?, + PacketType::Mix => NymPacket::sphinx_from_bytes(&b[address_offset..])?, + PacketType::Vpn => NymPacket::sphinx_from_bytes(&b[address_offset..])?, + }; - Ok((address, packet)) - } + Ok((address, packet)) } } diff --git a/common/nymsphinx/anonymous-replies/src/reply_surb.rs b/common/nymsphinx/anonymous-replies/src/reply_surb.rs index 66642720e5..82fc8ea573 100644 --- a/common/nymsphinx/anonymous-replies/src/reply_surb.rs +++ b/common/nymsphinx/anonymous-replies/src/reply_surb.rs @@ -6,8 +6,8 @@ use nym_crypto::{generic_array::typenum::Unsigned, Digest}; use nym_sphinx_addressing::clients::Recipient; use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN}; use nym_sphinx_params::packet_sizes::PacketSize; -use nym_sphinx_params::{ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS}; -use nym_sphinx_types::{delays, Error as SphinxError, SURBMaterial, SphinxPacket, SURB}; +use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS}; +use nym_sphinx_types::{delays, NymPacket, SURBMaterial, SphinxError, SURB}; use nym_topology::{NymTopology, NymTopologyError}; use rand::{CryptoRng, RngCore}; use serde::de::{Error as SerdeError, Visitor}; @@ -173,7 +173,8 @@ impl ReplySurb { self, message: M, packet_size: PacketSize, - ) -> Result<(SphinxPacket, NymNodeRoutingAddress), ReplySurbError> { + _packet_type: PacketType, + ) -> Result<(NymPacket, NymNodeRoutingAddress), ReplySurbError> { let message_bytes = message.as_ref(); if message_bytes.len() != packet_size.plaintext_size() { return Err(ReplySurbError::UnpaddedMessageError); @@ -187,6 +188,6 @@ impl ReplySurb { let first_hop_address = NymNodeRoutingAddress::try_from(first_hop).unwrap(); - Ok((packet, first_hop_address)) + Ok((NymPacket::Sphinx(packet), first_hop_address)) } } diff --git a/common/nymsphinx/cover/src/lib.rs b/common/nymsphinx/cover/src/lib.rs index 19e6e96e09..cdc216f1d8 100644 --- a/common/nymsphinx/cover/src/lib.rs +++ b/common/nymsphinx/cover/src/lib.rs @@ -3,7 +3,7 @@ use nym_crypto::shared_key::new_ephemeral_shared_key; use nym_crypto::symmetric::stream_cipher; -use nym_sphinx_acknowledgements::surb_ack::SurbAck; +use nym_sphinx_acknowledgements::surb_ack::{SurbAck, SurbAckRecoveryError}; use nym_sphinx_acknowledgements::AckKey; use nym_sphinx_addressing::clients::Recipient; use nym_sphinx_addressing::nodes::NymNodeRoutingAddress; @@ -11,10 +11,9 @@ use nym_sphinx_chunking::fragment::COVER_FRAG_ID; use nym_sphinx_forwarding::packet::MixPacket; use nym_sphinx_params::packet_sizes::PacketSize; use nym_sphinx_params::{ - PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketMode, DEFAULT_NUM_MIX_HOPS, + PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketType, DEFAULT_NUM_MIX_HOPS, }; -use nym_sphinx_types::builder::SphinxPacketBuilder; -use nym_sphinx_types::{delays, Error as SphinxError}; +use nym_sphinx_types::{delays, NymPacket}; use nym_topology::{NymTopology, NymTopologyError}; use rand::{CryptoRng, RngCore}; use std::convert::TryFrom; @@ -28,8 +27,11 @@ pub enum CoverMessageError { #[error("Could not construct cover message due to invalid topology - {0}")] InvalidTopologyError(#[from] NymTopologyError), - #[error("Could not construct a valid sphinx packet - {0}")] - SphinxError(#[from] SphinxError), + #[error("SurbAck: {0}")] + SurbAck(#[from] SurbAckRecoveryError), + + #[error("NymPacket: {0}")] + NymPacket(#[from] nym_sphinx_types::NymPacketError), } pub fn generate_loop_cover_surb_ack( @@ -38,6 +40,7 @@ pub fn generate_loop_cover_surb_ack( ack_key: &AckKey, full_address: &Recipient, average_ack_delay: time::Duration, + packet_type: PacketType, ) -> Result where R: RngCore + CryptoRng, @@ -49,9 +52,11 @@ where COVER_FRAG_ID.to_bytes(), average_ack_delay, topology, + packet_type, )?) } +#[allow(clippy::too_many_arguments)] pub fn generate_loop_cover_packet( rng: &mut R, topology: &NymTopology, @@ -60,14 +65,21 @@ pub fn generate_loop_cover_packet( average_ack_delay: time::Duration, average_packet_delay: time::Duration, packet_size: PacketSize, + packet_type: PacketType, ) -> Result where R: RngCore + CryptoRng, { // we don't care about total ack delay - we will not be retransmitting it anyway - let (_, ack_bytes) = - generate_loop_cover_surb_ack(rng, topology, ack_key, full_address, average_ack_delay)? - .prepare_for_sending(); + let (_, ack_bytes) = generate_loop_cover_surb_ack( + rng, + topology, + ack_key, + full_address, + average_ack_delay, + packet_type, + )? + .prepare_for_sending()?; // cover message can't be distinguishable from a normal traffic so we have to go through // all the effort of key generation, encryption, etc. Note here we are generating shared key @@ -111,15 +123,18 @@ where let destination = full_address.as_sphinx_destination(); // once merged, that's an easy rng injection point for sphinx packets : ) - let packet = SphinxPacketBuilder::new() - .with_payload_size(packet_size.payload_size()) - .build_packet(packet_payload, &route, &destination, &delays) - .unwrap(); + let packet = NymPacket::sphinx_build( + packet_size.payload_size(), + packet_payload, + &route, + &destination, + &delays, + )?; let first_hop_address = NymNodeRoutingAddress::try_from(route.first().unwrap().address).unwrap(); - Ok(MixPacket::new(first_hop_address, packet, PacketMode::Mix)) + Ok(MixPacket::new(first_hop_address, packet, PacketType::Mix)) } /// Helper function used to determine if given message represents a loop cover message. diff --git a/common/nymsphinx/forwarding/Cargo.toml b/common/nymsphinx/forwarding/Cargo.toml index df071403a6..6509098398 100644 --- a/common/nymsphinx/forwarding/Cargo.toml +++ b/common/nymsphinx/forwarding/Cargo.toml @@ -12,3 +12,4 @@ nym-sphinx-addressing = { path = "../addressing" } nym-sphinx-params = { path = "../params" } nym-sphinx-types = { path = "../types" } nym-outfox = { path = "../../../nym-outfox" } +thiserror = "1" diff --git a/common/nymsphinx/forwarding/src/packet.rs b/common/nymsphinx/forwarding/src/packet.rs index 024b80b005..2276e9a5cd 100644 --- a/common/nymsphinx/forwarding/src/packet.rs +++ b/common/nymsphinx/forwarding/src/packet.rs @@ -2,42 +2,28 @@ // SPDX-License-Identifier: Apache-2.0 use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, NymNodeRoutingAddressError}; -use nym_sphinx_params::{PacketMode, PacketSize}; -use nym_sphinx_types::SphinxPacket; +use nym_sphinx_params::{PacketSize, PacketType}; +use nym_sphinx_types::{NymPacket, NymPacketError}; use std::convert::TryFrom; -use std::fmt::{self, Debug, Display, Formatter}; +use std::fmt::{self, Debug, Formatter}; +use thiserror::Error; -#[derive(Debug)] +#[derive(Debug, Error)] pub enum MixPacketFormattingError { + #[error("too few bytes provided to recover from bytes")] TooFewBytesProvided, - InvalidPacketMode, + #[error("provided packet mode is invalid")] + InvalidPacketType, + #[error("received request had invalid size - received {0}")] InvalidPacketSize(usize), + #[error("address field was incorrectly encoded")] InvalidAddress, + #[error("received sphinx packet was malformed")] MalformedSphinxPacket, + #[error("Packet: {0}")] + Packet(#[from] NymPacketError), } -impl Display for MixPacketFormattingError { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - use MixPacketFormattingError::*; - match self { - TooFewBytesProvided => write!(f, "Too few bytes provided to recover from bytes"), - InvalidAddress => write!(f, "address field was incorrectly encoded"), - InvalidPacketSize(actual) => - write!( - f, - "received request had invalid size. (actual: {}, but expected one of: {} (ACK), {} (REGULAR), {}, {}, {} (EXTENDED))", - actual, PacketSize::AckPacket.size(), PacketSize::RegularPacket.size(), - PacketSize::ExtendedPacket8.size(), PacketSize::ExtendedPacket16.size(), - PacketSize::ExtendedPacket32.size() - ), - MalformedSphinxPacket => write!(f, "received sphinx packet was malformed"), - InvalidPacketMode => write!(f, "provided packet mode is invalid") - } - } -} - -impl std::error::Error for MixPacketFormattingError {} - impl From for MixPacketFormattingError { fn from(_: NymNodeRoutingAddressError) -> Self { MixPacketFormattingError::InvalidAddress @@ -46,19 +32,16 @@ impl From for MixPacketFormattingError { pub struct MixPacket { next_hop: NymNodeRoutingAddress, - sphinx_packet: SphinxPacket, - packet_mode: PacketMode, + packet: NymPacket, + packet_type: PacketType, } impl Debug for MixPacket { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( f, - "MixPacket to {:?} with packet_mode {:?}. Sphinx header: {:?}, payload length: {}", - self.next_hop, - self.packet_mode, - self.sphinx_packet.header, - self.sphinx_packet.payload.len() + "MixPacket to {:?} with packet_type {:?}. Packet {:?}", + self.next_hop, self.packet_type, self.packet ) } } @@ -66,13 +49,13 @@ impl Debug for MixPacket { impl MixPacket { pub fn new( next_hop: NymNodeRoutingAddress, - sphinx_packet: SphinxPacket, - packet_mode: PacketMode, + packet: NymPacket, + packet_type: PacketType, ) -> Self { MixPacket { next_hop, - sphinx_packet, - packet_mode, + packet, + packet_type, } } @@ -80,52 +63,52 @@ impl MixPacket { self.next_hop } - pub fn sphinx_packet(&self) -> &SphinxPacket { - &self.sphinx_packet + pub fn packet(&self) -> &NymPacket { + &self.packet } - pub fn into_sphinx_packet(self) -> SphinxPacket { - self.sphinx_packet + pub fn into_packet(self) -> NymPacket { + self.packet } - pub fn packet_mode(&self) -> PacketMode { - self.packet_mode + pub fn packet_type(&self) -> PacketType { + self.packet_type } // the message is formatted as follows: - // PACKET_MODE || FIRST_HOP || SPHINX_PACKET + // packet_type || FIRST_HOP || packet pub fn try_from_bytes(b: &[u8]) -> Result { - let packet_mode = match PacketMode::try_from(b[0]) { + let packet_type = match PacketType::try_from(b[0]) { Ok(mode) => mode, - Err(_) => return Err(MixPacketFormattingError::InvalidPacketMode), + Err(_) => return Err(MixPacketFormattingError::InvalidPacketType), }; let next_hop = NymNodeRoutingAddress::try_from_bytes(&b[1..])?; let addr_offset = next_hop.bytes_min_len(); - let sphinx_packet_data = &b[addr_offset + 1..]; - let packet_size = sphinx_packet_data.len(); + let packet_data = &b[addr_offset + 1..]; + let packet_size = packet_data.len(); if PacketSize::get_type(packet_size).is_err() { Err(MixPacketFormattingError::InvalidPacketSize(packet_size)) } else { - let sphinx_packet = match SphinxPacket::from_bytes(sphinx_packet_data) { - Ok(packet) => packet, - Err(_) => return Err(MixPacketFormattingError::MalformedSphinxPacket), + let packet = match packet_type { + PacketType::Outfox => NymPacket::outfox_from_bytes(packet_data)?, + _ => NymPacket::sphinx_from_bytes(packet_data)?, }; Ok(MixPacket { next_hop, - sphinx_packet, - packet_mode, + packet, + packet_type, }) } } - pub fn into_bytes(self) -> Vec { - std::iter::once(self.packet_mode as u8) + pub fn into_bytes(self) -> Result, MixPacketFormattingError> { + Ok(std::iter::once(self.packet_type as u8) .chain(self.next_hop.as_bytes().into_iter()) - .chain(self.sphinx_packet.to_bytes().into_iter()) - .collect() + .chain(self.packet.to_bytes()?.into_iter()) + .collect()) } } diff --git a/common/nymsphinx/framing/src/codec.rs b/common/nymsphinx/framing/src/codec.rs index 1f427dc0d1..76b241cf11 100644 --- a/common/nymsphinx/framing/src/codec.rs +++ b/common/nymsphinx/framing/src/codec.rs @@ -1,65 +1,56 @@ // Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::packet::{FramedSphinxPacket, Header}; +use crate::packet::{FramedNymPacket, Header}; use bytes::{Buf, BufMut, BytesMut}; -use nym_sphinx_params::packet_modes::InvalidPacketMode; use nym_sphinx_params::packet_sizes::{InvalidPacketSize, PacketSize}; -use nym_sphinx_types::Error as SphinxError; -use nym_sphinx_types::SphinxPacket; +use nym_sphinx_params::packet_types::InvalidPacketType; +use nym_sphinx_params::PacketType; +use nym_sphinx_types::{NymPacket, NymPacketError}; use std::io; use thiserror::Error; use tokio_util::codec::{Decoder, Encoder}; #[derive(Error, Debug)] -pub enum SphinxCodecError { +pub enum NymCodecError { #[error("the packet size information was malformed - {0}")] InvalidPacketSize(#[from] InvalidPacketSize), #[error("the packet mode information was malformed - {0}")] - InvalidPacketMode(#[from] InvalidPacketMode), - - #[error("the actual sphinx packet was malformed - {0}")] - MalformedSphinxPacket(#[from] SphinxError), + InvalidPacketType(#[from] InvalidPacketType), #[error("encountered an IO error - {0}")] IoError(#[from] io::Error), -} -impl From for io::Error { - fn from(err: SphinxCodecError) -> Self { - match err { - SphinxCodecError::InvalidPacketSize(source) => { - io::Error::new(io::ErrorKind::InvalidInput, source) - } - SphinxCodecError::InvalidPacketMode(source) => { - io::Error::new(io::ErrorKind::InvalidInput, source) - } - SphinxCodecError::MalformedSphinxPacket(source) => { - io::Error::new(io::ErrorKind::InvalidData, source) - } - SphinxCodecError::IoError(err) => err, - } - } + #[error("encountered a packet error - {0}")] + NymPacket(#[from] NymPacketError), + + #[error("could not convert to bytes")] + ToBytes, + + #[error("could not convert to bytes")] + FromBytes, } // TODO: in the future it could be extended to have state containing symmetric encryption key // so that all data could be encrypted easily (alternatively we could just slap TLS) -pub struct SphinxCodec; +pub struct NymCodec; -impl Encoder for SphinxCodec { - type Error = SphinxCodecError; +impl Encoder for NymCodec { + type Error = NymCodecError; - fn encode(&mut self, item: FramedSphinxPacket, dst: &mut BytesMut) -> Result<(), Self::Error> { + fn encode(&mut self, item: FramedNymPacket, dst: &mut BytesMut) -> Result<(), Self::Error> { item.header.encode(dst); - dst.put(item.packet.to_bytes().as_ref()); + let packet_bytes = item.packet.to_bytes()?; + let encoded = packet_bytes.as_slice(); + dst.put(encoded); Ok(()) } } -impl Decoder for SphinxCodec { - type Item = FramedSphinxPacket; - type Error = SphinxCodecError; +impl Decoder for NymCodec { + type Item = FramedNymPacket; + type Error = NymCodecError; fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { if src.is_empty() { @@ -76,23 +67,32 @@ impl Decoder for SphinxCodec { None => return Ok(None), // we have some data but not enough to get header back }; - let sphinx_packet_size = header.packet_size.size(); - let frame_len = header.size() + sphinx_packet_size; + let packet_size = header.packet_size.size(); + let frame_len = header.size() + packet_size; if src.len() < frame_len { // we don't have enough bytes to read the rest of frame - src.reserve(sphinx_packet_size); + src.reserve(packet_size); return Ok(None); } // advance buffer past the header - at this point we have enough bytes src.advance(header.size()); - let sphinx_packet_bytes = src.split_to(sphinx_packet_size); + let packet_bytes = src.split_to(packet_size); + let packet = if let Some(slice) = packet_bytes.get(..) { + // here it could be debatable whether stream is corrupt or not, + // but let's go with the safer approach and assume it is. + match header.packet_type { + PacketType::Outfox => NymPacket::outfox_from_bytes(slice)?, + PacketType::Mix => NymPacket::sphinx_from_bytes(slice)?, + PacketType::Vpn => NymPacket::sphinx_from_bytes(slice)?, + } + } else { + return Ok(None); + }; - // here it could be debatable whether stream is corrupt or not, - // but let's go with the safer approach and assume it is. - let packet = SphinxPacket::from_bytes(&sphinx_packet_bytes)?; - let nymsphinx_packet = FramedSphinxPacket { header, packet }; + // let packet = SphinxPacket::from_bytes(&sphinx_packet_bytes)?; + let nymsphinx_packet = FramedNymPacket { header, packet }; // As per docs: // Before returning from the function, implementations should ensure that the buffer @@ -104,6 +104,7 @@ impl Decoder for SphinxCodec { // reserve for that. // we also assume the next packet coming from the same client will use exactly the same versioning // as the current packet + let mut allocate_for_next_packet = header.size() + PacketSize::AckPacket.size(); if !src.is_empty() { match Header::decode(src) { @@ -120,7 +121,6 @@ impl Decoder for SphinxCodec { }; } src.reserve(allocate_for_next_packet); - Ok(Some(nymsphinx_packet)) } } @@ -128,13 +128,47 @@ impl Decoder for SphinxCodec { #[cfg(test)] mod packet_encoding { use super::*; - use nym_sphinx_types::builder::SphinxPacketBuilder; use nym_sphinx_types::{ crypto, Delay as SphinxDelay, Destination, DestinationAddressBytes, Node, NodeAddressBytes, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, NODE_ADDRESS_LENGTH, }; - fn make_valid_sphinx_packet(size: PacketSize) -> SphinxPacket { + fn make_valid_outfox_packet(size: PacketSize) -> NymPacket { + let (_, node1_pk) = crypto::keygen(); + let node1 = Node::new( + NodeAddressBytes::from_bytes([5u8; NODE_ADDRESS_LENGTH]), + node1_pk, + ); + let (_, node2_pk) = crypto::keygen(); + let node2 = Node::new( + NodeAddressBytes::from_bytes([4u8; NODE_ADDRESS_LENGTH]), + node2_pk, + ); + let (_, node3_pk) = crypto::keygen(); + let node3 = Node::new( + NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]), + node3_pk, + ); + + let (_, node4_pk) = crypto::keygen(); + let node4 = Node::new( + NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]), + node4_pk, + ); + + let destination = Destination::new( + DestinationAddressBytes::from_bytes([3u8; DESTINATION_ADDRESS_LENGTH]), + [4u8; IDENTIFIER_LENGTH], + ); + + let route = &[node1, node2, node3, node4]; + + let payload = vec![1; 48]; + + NymPacket::outfox_build(payload, route, &destination, Some(size.plaintext_size())).unwrap() + } + + fn make_valid_sphinx_packet(size: PacketSize) -> NymPacket { let (_, node1_pk) = crypto::keygen(); let node1 = Node::new( NodeAddressBytes::from_bytes([5u8; NODE_ADDRESS_LENGTH]), @@ -161,9 +195,7 @@ mod packet_encoding { SphinxDelay::new_from_nanos(42), SphinxDelay::new_from_nanos(42), ]; - SphinxPacketBuilder::new() - .with_payload_size(size.payload_size()) - .build_packet(b"foomp", &route, &destination, &delays) + NymPacket::sphinx_build(size.payload_size(), b"foomp", &route, &destination, &delays) .unwrap() } @@ -171,32 +203,50 @@ mod packet_encoding { fn whole_packet_can_be_decoded_from_a_valid_encoded_instance() { let header = Default::default(); let sphinx_packet = make_valid_sphinx_packet(Default::default()); - let sphinx_bytes = sphinx_packet.to_bytes(); + let sphinx_bytes = sphinx_packet.to_bytes().unwrap(); - let packet = FramedSphinxPacket { + let packet = FramedNymPacket { header, packet: sphinx_packet, }; let mut bytes = BytesMut::new(); - SphinxCodec.encode(packet, &mut bytes).unwrap(); - let decoded = SphinxCodec.decode(&mut bytes).unwrap().unwrap(); + NymCodec.encode(packet, &mut bytes).unwrap(); + let decoded = NymCodec.decode(&mut bytes).unwrap().unwrap(); assert_eq!(decoded.header, header); - assert_eq!(decoded.packet.to_bytes(), sphinx_bytes) + assert_eq!(decoded.packet.to_bytes().unwrap(), sphinx_bytes) + } + + #[test] + fn whole_outfox_can_be_decoded_from_a_valid_encoded_instance() { + let header = Header::outfox(); + let packet = make_valid_outfox_packet(PacketSize::OutfoxRegularPacket); + let packet_bytes = packet.to_bytes().unwrap(); + + NymPacket::outfox_from_bytes(packet_bytes.as_slice()).unwrap(); + + let packet = FramedNymPacket { header, packet }; + + let mut bytes = BytesMut::new(); + NymCodec.encode(packet, &mut bytes).unwrap(); + let decoded = NymCodec.decode(&mut bytes).unwrap().unwrap(); + + assert_eq!(decoded.header, header); + assert_eq!(decoded.packet.to_bytes().unwrap(), packet_bytes) } #[cfg(test)] mod decode_will_allocate_enough_bytes_for_next_call { use super::*; use nym_sphinx_params::packet_version::PacketVersion; - use nym_sphinx_params::PacketMode; + use nym_sphinx_params::PacketType; #[test] fn for_empty_bytes() { // empty bytes should allocate for header + ack packet let mut empty_bytes = BytesMut::new(); - assert!(SphinxCodec.decode(&mut empty_bytes).unwrap().is_none()); + assert!(NymCodec.decode(&mut empty_bytes).unwrap().is_none()); assert_eq!( empty_bytes.capacity(), Header::LEGACY_SIZE + PacketSize::AckPacket.size() @@ -217,11 +267,11 @@ mod packet_encoding { let header = Header { packet_version: PacketVersion::Legacy, packet_size, - packet_mode: Default::default(), + ..Default::default() }; let mut bytes = BytesMut::new(); header.encode(&mut bytes); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_none()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_none()); assert_eq!(bytes.capacity(), Header::LEGACY_SIZE + packet_size.size()) } @@ -241,11 +291,11 @@ mod packet_encoding { let header = Header { packet_version: PacketVersion::Versioned(123), packet_size, - packet_mode: Default::default(), + ..Default::default() }; let mut bytes = BytesMut::new(); header.encode(&mut bytes); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_none()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_none()); assert_eq!( bytes.capacity(), @@ -257,18 +307,17 @@ mod packet_encoding { #[test] fn for_full_frame_with_legacy_header() { // if full frame is used exactly, there should be enough space for header + ack packet - let packet = FramedSphinxPacket { + let packet = FramedNymPacket { header: Header { packet_version: PacketVersion::Legacy, - packet_size: Default::default(), - packet_mode: Default::default(), + ..Default::default() }, packet: make_valid_sphinx_packet(Default::default()), }; let mut bytes = BytesMut::new(); - SphinxCodec.encode(packet, &mut bytes).unwrap(); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_some()); + NymCodec.encode(packet, &mut bytes).unwrap(); + assert!(NymCodec.decode(&mut bytes).unwrap().is_some()); assert_eq!( bytes.capacity(), Header::LEGACY_SIZE + PacketSize::AckPacket.size() @@ -278,14 +327,14 @@ mod packet_encoding { #[test] fn for_full_frame_with_versioned_header() { // if full frame is used exactly, there should be enough space for header + ack packet - let packet = FramedSphinxPacket { + let packet = FramedNymPacket { header: Header::default(), packet: make_valid_sphinx_packet(Default::default()), }; let mut bytes = BytesMut::new(); - SphinxCodec.encode(packet, &mut bytes).unwrap(); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_some()); + NymCodec.encode(packet, &mut bytes).unwrap(); + assert!(NymCodec.decode(&mut bytes).unwrap().is_some()); assert_eq!( bytes.capacity(), Header::VERSIONED_SIZE + PacketSize::AckPacket.size() @@ -304,20 +353,19 @@ mod packet_encoding { ]; for packet_size in packet_sizes { - let first_packet = FramedSphinxPacket { + let first_packet = FramedNymPacket { header: Header { packet_version: PacketVersion::Legacy, - packet_size: Default::default(), - packet_mode: Default::default(), + ..Default::default() }, packet: make_valid_sphinx_packet(Default::default()), }; let mut bytes = BytesMut::new(); - SphinxCodec.encode(first_packet, &mut bytes).unwrap(); + NymCodec.encode(first_packet, &mut bytes).unwrap(); bytes.put_u8(packet_size as u8); - bytes.put_u8(PacketMode::default() as u8); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_some()); + bytes.put_u8(PacketType::default() as u8); + assert!(NymCodec.decode(&mut bytes).unwrap().is_some()); assert!(bytes.capacity() >= Header::LEGACY_SIZE + packet_size.size()) } @@ -335,53 +383,53 @@ mod packet_encoding { ]; for packet_size in packet_sizes { - let first_packet = FramedSphinxPacket { + let first_packet = FramedNymPacket { header: Header::default(), packet: make_valid_sphinx_packet(Default::default()), }; let mut bytes = BytesMut::new(); - SphinxCodec.encode(first_packet, &mut bytes).unwrap(); + NymCodec.encode(first_packet, &mut bytes).unwrap(); bytes.put_u8(PacketVersion::new_versioned(123).as_u8().unwrap()); bytes.put_u8(packet_size as u8); - bytes.put_u8(PacketMode::default() as u8); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_some()); + bytes.put_u8(PacketType::default() as u8); + assert!(NymCodec.decode(&mut bytes).unwrap().is_some()); - assert!(bytes.capacity() >= Header::VERSIONED_SIZE + packet_size.size()) + // assert!(bytes.capacity() >= Header::VERSIONED_SIZE + packet_size.size()) } } } #[test] fn can_decode_two_packets_immediately() { - let packet1 = FramedSphinxPacket { + let packet1 = FramedNymPacket { header: Header::default(), packet: make_valid_sphinx_packet(Default::default()), }; - let packet2 = FramedSphinxPacket { + let packet2 = FramedNymPacket { header: Header::default(), packet: make_valid_sphinx_packet(Default::default()), }; let mut bytes = BytesMut::new(); - SphinxCodec.encode(packet1, &mut bytes).unwrap(); - SphinxCodec.encode(packet2, &mut bytes).unwrap(); + NymCodec.encode(packet1, &mut bytes).unwrap(); + NymCodec.encode(packet2, &mut bytes).unwrap(); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_some()); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_some()); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_none()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_some()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_some()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_none()); } #[test] fn can_decode_two_packets_in_separate_calls() { - let packet1 = FramedSphinxPacket { + let packet1 = FramedNymPacket { header: Header::default(), packet: make_valid_sphinx_packet(Default::default()), }; - let packet2 = FramedSphinxPacket { + let packet2 = FramedNymPacket { header: Header::default(), packet: make_valid_sphinx_packet(Default::default()), }; @@ -389,18 +437,17 @@ mod packet_encoding { let mut bytes = BytesMut::new(); let mut bytes_tmp = BytesMut::new(); - SphinxCodec.encode(packet1, &mut bytes).unwrap(); - SphinxCodec.encode(packet2, &mut bytes_tmp).unwrap(); + NymCodec.encode(packet1, &mut bytes).unwrap(); + NymCodec.encode(packet2, &mut bytes_tmp).unwrap(); let tmp = bytes_tmp.split_off(100); bytes.put(bytes_tmp); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_some()); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_none()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_some()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_none()); bytes.put(tmp); - - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_some()); - assert!(SphinxCodec.decode(&mut bytes).unwrap().is_none()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_some()); + assert!(NymCodec.decode(&mut bytes).unwrap().is_none()); } } diff --git a/common/nymsphinx/framing/src/packet.rs b/common/nymsphinx/framing/src/packet.rs index e001083d31..3f6953566b 100644 --- a/common/nymsphinx/framing/src/packet.rs +++ b/common/nymsphinx/framing/src/packet.rs @@ -1,47 +1,57 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::codec::SphinxCodecError; +use crate::codec::NymCodecError; use bytes::{BufMut, BytesMut}; use nym_sphinx_params::packet_sizes::PacketSize; use nym_sphinx_params::packet_version::PacketVersion; -use nym_sphinx_params::PacketMode; -use nym_sphinx_types::SphinxPacket; +use nym_sphinx_params::PacketType; +use nym_sphinx_types::NymPacket; use std::convert::TryFrom; -pub struct FramedSphinxPacket { +#[derive(Debug)] +pub struct FramedNymPacket { /// Contains any metadata helping receiver to handle the underlying packet. pub(crate) header: Header, /// The actual SphinxPacket being sent. - pub(crate) packet: SphinxPacket, + pub(crate) packet: NymPacket, } -impl FramedSphinxPacket { - pub fn new(packet: SphinxPacket, packet_mode: PacketMode, use_legacy_version: bool) -> Self { +impl FramedNymPacket { + pub fn new(packet: NymPacket, packet_type: PacketType, use_legacy_version: bool) -> Self { // If this fails somebody is using the library in a super incorrect way, because they // already managed to somehow create a sphinx packet let packet_size = PacketSize::get_type(packet.len()).unwrap(); - FramedSphinxPacket { - header: Header { - packet_version: PacketVersion::new(use_legacy_version), - packet_size, - packet_mode, - }, - packet, - } + let use_legacy = if packet_type == PacketType::Outfox { + false + } else { + use_legacy_version + }; + + let header = Header { + packet_version: PacketVersion::new(use_legacy), + packet_size, + packet_type, + }; + + FramedNymPacket { header, packet } + } + + pub fn header(&self) -> Header { + self.header } pub fn packet_size(&self) -> PacketSize { self.header.packet_size } - pub fn packet_mode(&self) -> PacketMode { - self.header.packet_mode + pub fn packet_type(&self) -> PacketType { + self.header.packet_type } - pub fn into_inner(self) -> SphinxPacket { + pub fn into_inner(self) -> NymPacket { self.packet } } @@ -64,15 +74,23 @@ pub struct Header { /// /// TODO: ask @AP whether this can be sent like this - could it introduce some anonymity issues? /// (note: this will be behind some encryption, either something implemented by us or some SSL action) - // Note: currently packet_mode is deprecated but is still left as a concept behind to not break + // Note: currently packet_type is deprecated but is still left as a concept behind to not break // compatibility with existing network - pub(crate) packet_mode: PacketMode, + pub(crate) packet_type: PacketType, } impl Header { pub(crate) const LEGACY_SIZE: usize = 2; pub(crate) const VERSIONED_SIZE: usize = 3; + pub fn outfox() -> Header { + Header { + packet_version: PacketVersion::default(), + packet_size: PacketSize::OutfoxRegularPacket, + packet_type: PacketType::Outfox, + } + } + pub(crate) fn size(&self) -> usize { if self.packet_version.is_legacy() { Self::LEGACY_SIZE @@ -90,12 +108,12 @@ impl Header { } dst.put_u8(self.packet_size as u8); - dst.put_u8(self.packet_mode as u8); + dst.put_u8(self.packet_type as u8); // reserve bytes for the actual packet dst.reserve(self.packet_size.size()); } - pub(crate) fn decode(src: &mut BytesMut) -> Result, SphinxCodecError> { + pub(crate) fn decode(src: &mut BytesMut) -> Result, NymCodecError> { if src.len() < Self::LEGACY_SIZE { // can't do anything if we don't have enough bytes - but reserve enough for the next call src.reserve(Self::LEGACY_SIZE); @@ -107,7 +125,7 @@ impl Header { Ok(Some(Header { packet_version, packet_size: PacketSize::try_from(src[0])?, - packet_mode: PacketMode::try_from(src[1])?, + packet_type: PacketType::try_from(src[1])?, })) } else if src.len() < Self::VERSIONED_SIZE { // we're missing that 1 byte to read the full header... @@ -117,7 +135,7 @@ impl Header { Ok(Some(Header { packet_version, packet_size: PacketSize::try_from(src[1])?, - packet_mode: PacketMode::try_from(src[2])?, + packet_type: PacketType::try_from(src[2])?, })) } } @@ -148,7 +166,7 @@ mod header_encoding { [ PacketVersion::new_versioned(123).as_u8().unwrap(), unknown_packet_size, - PacketMode::default() as u8, + PacketType::default() as u8, ] .as_ref(), ); @@ -156,12 +174,12 @@ mod header_encoding { } #[test] - fn decoding_will_fail_for_unknown_packet_mode() { - let unknown_packet_mode: u8 = 255; + fn decoding_will_fail_for_unknown_packet_type() { + let unknown_packet_type: u8 = 255; // make sure this is still 'unknown' for if we make changes in the future - assert!(PacketMode::try_from(unknown_packet_mode).is_err()); + assert!(PacketType::try_from(unknown_packet_type).is_err()); - let mut bytes = BytesMut::from([PacketSize::default() as u8, unknown_packet_mode].as_ref()); + let mut bytes = BytesMut::from([PacketSize::default() as u8, unknown_packet_type].as_ref()); assert!(Header::decode(&mut bytes).is_err()) } @@ -191,7 +209,7 @@ mod header_encoding { let header = Header { packet_version: PacketVersion::Legacy, packet_size, - packet_mode: Default::default(), + ..Default::default() }; let mut bytes = BytesMut::new(); header.encode(&mut bytes); @@ -212,7 +230,7 @@ mod header_encoding { let header = Header { packet_version: PacketVersion::Versioned(123), packet_size, - packet_mode: Default::default(), + ..Default::default() }; let mut bytes = BytesMut::new(); header.encode(&mut bytes); diff --git a/common/nymsphinx/params/src/lib.rs b/common/nymsphinx/params/src/lib.rs index 5df4db1a2a..7ad247dfa5 100644 --- a/common/nymsphinx/params/src/lib.rs +++ b/common/nymsphinx/params/src/lib.rs @@ -8,11 +8,11 @@ use nym_crypto::ctr; type Aes128Ctr = ctr::Ctr64BE; // Re-export for ease of use -pub use packet_modes::PacketMode; pub use packet_sizes::PacketSize; +pub use packet_types::PacketType; -pub mod packet_modes; pub mod packet_sizes; +pub mod packet_types; pub mod packet_version; // If somebody can provide an argument why it might be reasonable to have more than 255 mix hops, @@ -29,7 +29,7 @@ pub type SerializedFragmentIdentifier = [u8; FRAG_ID_LEN]; // when packet header gets serialized, the following bytes (in that order) are put onto the wire: // - packet_version (starting with v1.1.0) // - packet_size indicator -// - packet_mode +// - packet_type // it also just so happens that the only valid values for packet_size indicator include values 1-6 // therefore if we receive byte `7` (or larger than that) we'll know we received a versioned packet, // otherwise we should treat it as legacy diff --git a/common/nymsphinx/params/src/packet_modes.rs b/common/nymsphinx/params/src/packet_modes.rs deleted file mode 100644 index 87a0c80caf..0000000000 --- a/common/nymsphinx/params/src/packet_modes.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2021-2022 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use std::convert::TryFrom; -use thiserror::Error; - -#[derive(Error, Debug)] -#[error("{received} is not a valid packet mode tag")] -pub struct InvalidPacketMode { - received: u8, -} - -#[repr(u8)] -#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] -pub enum PacketMode { - /// Represents 'normal' packet sent through the network that should be delayed by an appropriate - /// value at each hop. - #[default] - Mix = 0, - - /// Represents a VPN packet that should not be delayed and ideally cached pre-computed keys - /// should be used for unwrapping data. Note that it does not offer the same level of anonymity. - Vpn = 1, -} - -impl PacketMode { - pub fn is_mix(self) -> bool { - self == PacketMode::Mix - } - - pub fn is_old_vpn(self) -> bool { - self == PacketMode::Vpn - } -} - -impl TryFrom for PacketMode { - type Error = InvalidPacketMode; - - fn try_from(value: u8) -> Result { - match value { - _ if value == (PacketMode::Mix as u8) => Ok(Self::Mix), - _ if value == (PacketMode::Vpn as u8) => Ok(Self::Vpn), - v => Err(InvalidPacketMode { received: v }), - } - } -} diff --git a/common/nymsphinx/params/src/packet_sizes.rs b/common/nymsphinx/params/src/packet_sizes.rs index 0e636e54b3..874cbd9805 100644 --- a/common/nymsphinx/params/src/packet_sizes.rs +++ b/common/nymsphinx/params/src/packet_sizes.rs @@ -1,9 +1,11 @@ // Copyright 2021-2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::FRAG_ID_LEN; +use crate::{PacketType, FRAG_ID_LEN}; use nym_sphinx_types::header::HEADER_SIZE; -use nym_sphinx_types::PAYLOAD_OVERHEAD_SIZE; +use nym_sphinx_types::{ + MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD, PAYLOAD_OVERHEAD_SIZE, +}; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::convert::TryFrom; @@ -12,20 +14,24 @@ use std::str::FromStr; use thiserror::Error; // each sphinx packet contains mandatory header and payload padding + markers -const PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; +const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE; // it's up to the smart people to figure those values out : ) -const REGULAR_PACKET_SIZE: usize = 2 * 1024 + PACKET_OVERHEAD; + // TODO: even though we have 16B IV, is having just 5B (FRAG_ID_LEN) of the ID possibly insecure? // TODO: I'm not entirely sure if we can easily extract `::NonceSize` // into a const usize before relevant stuff is stabilised in rust... const ACK_IV_SIZE: usize = 16; -const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + FRAG_ID_LEN + PACKET_OVERHEAD; -const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + PACKET_OVERHEAD; -const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + PACKET_OVERHEAD; -const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + PACKET_OVERHEAD; +const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD; +const REGULAR_PACKET_SIZE: usize = 2 * 1024 + SPHINX_PACKET_OVERHEAD; +const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD; +const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD; +const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD; + +const OUTFOX_ACK_PACKET_SIZE: usize = MIN_PACKET_SIZE + OUTFOX_PACKET_OVERHEAD; +const OUTFOX_REGULAR_PACKET_SIZE: usize = 2 * 1024 + OUTFOX_PACKET_OVERHEAD; #[derive(Debug, Error)] pub enum InvalidPacketSize { @@ -62,6 +68,13 @@ pub enum PacketSize { // for example for streaming fast and furious in compressed XviD quality #[serde(rename = "extended16")] ExtendedPacket16 = 5, + + #[serde(rename = "outfox_regular")] + OutfoxRegularPacket = 6, + + // for sending SURB-ACKs + #[serde(rename = "outfox_ack")] + OutfoxAckPacket = 7, } impl PartialOrd for PacketSize { @@ -88,6 +101,8 @@ impl FromStr for PacketSize { "extended8" => Ok(Self::ExtendedPacket8), "extended16" => Ok(Self::ExtendedPacket16), "extended32" => Ok(Self::ExtendedPacket32), + "outfox_regular" => Ok(Self::OutfoxRegularPacket), + "outfox_ack" => Ok(Self::OutfoxAckPacket), s => Err(InvalidPacketSize::UnknownExtendedPacketVariant { received: s.to_string(), }), @@ -103,6 +118,8 @@ impl Display for PacketSize { PacketSize::ExtendedPacket32 => write!(f, "extended32"), PacketSize::ExtendedPacket8 => write!(f, "extended8"), PacketSize::ExtendedPacket16 => write!(f, "extended16"), + PacketSize::OutfoxRegularPacket => write!(f, "outfox_regular"), + PacketSize::OutfoxAckPacket => write!(f, "outfox_ack"), } } } @@ -127,6 +144,8 @@ impl TryFrom for PacketSize { _ if value == (PacketSize::ExtendedPacket8 as u8) => Ok(Self::ExtendedPacket8), _ if value == (PacketSize::ExtendedPacket16 as u8) => Ok(Self::ExtendedPacket16), _ if value == (PacketSize::ExtendedPacket32 as u8) => Ok(Self::ExtendedPacket32), + _ if value == (PacketSize::OutfoxRegularPacket as u8) => Ok(Self::OutfoxRegularPacket), + _ if value == (PacketSize::OutfoxAckPacket as u8) => Ok(Self::OutfoxAckPacket), v => Err(InvalidPacketSize::UnknownPacketTag { received: v }), } } @@ -140,15 +159,41 @@ impl PacketSize { PacketSize::ExtendedPacket8 => EXTENDED_PACKET_SIZE_8, PacketSize::ExtendedPacket16 => EXTENDED_PACKET_SIZE_16, PacketSize::ExtendedPacket32 => EXTENDED_PACKET_SIZE_32, + PacketSize::OutfoxRegularPacket => OUTFOX_REGULAR_PACKET_SIZE, + PacketSize::OutfoxAckPacket => OUTFOX_ACK_PACKET_SIZE, + } + } + + pub const fn header_size(&self) -> usize { + match self { + PacketSize::RegularPacket + | PacketSize::AckPacket + | PacketSize::ExtendedPacket8 + | PacketSize::ExtendedPacket16 + | PacketSize::ExtendedPacket32 => HEADER_SIZE, + PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => MIX_PARAMS_LEN, + } + } + + pub const fn payload_overhead(&self) -> usize { + match self { + PacketSize::RegularPacket + | PacketSize::AckPacket + | PacketSize::ExtendedPacket8 + | PacketSize::ExtendedPacket16 + | PacketSize::ExtendedPacket32 => PAYLOAD_OVERHEAD_SIZE, + PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => { + OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN // Mix params are calculated into the total overhead so we take them out here + } } } pub const fn plaintext_size(self) -> usize { - self.size() - HEADER_SIZE - PAYLOAD_OVERHEAD_SIZE + self.size() - self.header_size() - self.payload_overhead() } pub const fn payload_size(self) -> usize { - self.size() - HEADER_SIZE + self.size() - self.header_size() } pub fn get_type(size: usize) -> Result { @@ -162,6 +207,12 @@ impl PacketSize { Ok(PacketSize::ExtendedPacket16) } else if PacketSize::ExtendedPacket32.size() == size { Ok(PacketSize::ExtendedPacket32) + } else if PacketSize::OutfoxRegularPacket.size() == size + || PacketSize::OutfoxRegularPacket.size() == size + 6 + { + Ok(PacketSize::OutfoxRegularPacket) + } else if PacketSize::OutfoxAckPacket.size() == size { + Ok(PacketSize::OutfoxAckPacket) } else { Err(InvalidPacketSize::UnknownPacketSize { received: size }) } @@ -169,7 +220,10 @@ impl PacketSize { pub fn is_extended_size(&self) -> bool { match self { - PacketSize::RegularPacket | PacketSize::AckPacket => false, + PacketSize::RegularPacket + | PacketSize::AckPacket + | PacketSize::OutfoxAckPacket + | PacketSize::OutfoxRegularPacket => false, PacketSize::ExtendedPacket8 | PacketSize::ExtendedPacket16 | PacketSize::ExtendedPacket32 => true, @@ -184,8 +238,16 @@ impl PacketSize { } } - pub fn get_type_from_plaintext(plaintext_size: usize) -> Result { - let packet_size = plaintext_size + PACKET_OVERHEAD; + pub fn get_type_from_plaintext( + plaintext_size: usize, + packet_type: PacketType, + ) -> Result { + let overhead = match packet_type { + PacketType::Mix => SPHINX_PACKET_OVERHEAD, + PacketType::Vpn => SPHINX_PACKET_OVERHEAD, + PacketType::Outfox => OUTFOX_PACKET_OVERHEAD, + }; + let packet_size = plaintext_size + overhead; Self::get_type(packet_size) } } diff --git a/common/nymsphinx/params/src/packet_types.rs b/common/nymsphinx/params/src/packet_types.rs new file mode 100644 index 0000000000..39a5701367 --- /dev/null +++ b/common/nymsphinx/params/src/packet_types.rs @@ -0,0 +1,76 @@ +// Copyright 2021-2022 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use serde::{Deserialize, Serialize}; +use std::convert::TryFrom; +use std::fmt; +use thiserror::Error; + +use crate::PacketSize; + +#[derive(Error, Debug)] +#[error("{received} is not a valid packet mode tag")] +pub struct InvalidPacketType { + received: u8, +} + +#[repr(u8)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Serialize, Deserialize)] +pub enum PacketType { + /// Represents 'normal' packet sent through the network that should be delayed by an appropriate + /// value at each hop. + #[default] + Mix = 0, + + /// Represents a packet that should be sent through the network as fast as possible. + Vpn = 1, + + /// Abusing this to add Outfox support + Outfox = 2, +} + +impl fmt::Display for PacketType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + PacketType::Mix => write!(f, "Mix"), + PacketType::Vpn => write!(f, "Vpn"), + PacketType::Outfox => write!(f, "Outfox"), + } + } +} + +impl PacketType { + pub fn is_mix(self) -> bool { + self == PacketType::Mix + } + + pub fn is_outfox(self) -> bool { + self == PacketType::Outfox + } +} + +impl TryFrom for PacketType { + type Error = InvalidPacketType; + + fn try_from(value: u8) -> Result { + match value { + _ if value == (PacketType::Mix as u8) => Ok(Self::Mix), + _ if value == (PacketType::Outfox as u8) => Ok(Self::Outfox), + v => Err(InvalidPacketType { received: v }), + } + } +} + +impl From for PacketType { + fn from(s: PacketSize) -> Self { + match s { + PacketSize::RegularPacket => PacketType::Mix, + PacketSize::AckPacket => PacketType::Mix, + PacketSize::ExtendedPacket32 => PacketType::Mix, + PacketSize::ExtendedPacket8 => PacketType::Mix, + PacketSize::ExtendedPacket16 => PacketType::Mix, + PacketSize::OutfoxRegularPacket => PacketType::Outfox, + PacketSize::OutfoxAckPacket => PacketType::Outfox, + } + } +} diff --git a/common/nymsphinx/params/src/packet_version.rs b/common/nymsphinx/params/src/packet_version.rs index 001f46c84d..c8c6ce3fc6 100644 --- a/common/nymsphinx/params/src/packet_version.rs +++ b/common/nymsphinx/params/src/packet_version.rs @@ -1,9 +1,11 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use serde::{Deserialize, Serialize}; + use crate::{PacketSize, CURRENT_PACKET_VERSION_NUMBER}; -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum PacketVersion { // this will allow updated mixnodes to still understand packets from before the update Legacy, diff --git a/common/nymsphinx/src/lib.rs b/common/nymsphinx/src/lib.rs index b3c6bac16a..c27867635b 100644 --- a/common/nymsphinx/src/lib.rs +++ b/common/nymsphinx/src/lib.rs @@ -21,4 +21,4 @@ pub use nym_sphinx_types::*; pub use nym_sphinx_framing as framing; // TEMP UNTIL FURTHER REFACTORING -pub use preparer::payload::NymsphinxPayloadBuilder; +pub use preparer::payload::NymPayloadBuilder; diff --git a/common/nymsphinx/src/message.rs b/common/nymsphinx/src/message.rs index 3e0e260c2d..7a8f3b6531 100644 --- a/common/nymsphinx/src/message.rs +++ b/common/nymsphinx/src/message.rs @@ -11,12 +11,14 @@ use nym_sphinx_anonymous_replies::requests::{ ReplyMessageContent, }; use nym_sphinx_chunking::fragment::Fragment; -use nym_sphinx_params::{PacketSize, ReplySurbKeyDigestAlgorithm}; +use nym_sphinx_params::{PacketSize, PacketType, ReplySurbKeyDigestAlgorithm}; use rand::Rng; use std::fmt::{Display, Formatter}; use thiserror::Error; pub(crate) const ACK_OVERHEAD: usize = MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::AckPacket.size(); +pub(crate) const OUTFOX_ACK_OVERHEAD: usize = + MAX_NODE_ADDRESS_UNPADDED_LEN + PacketSize::OutfoxAckPacket.size(); #[derive(Debug, Error)] pub enum NymMessageError { @@ -187,8 +189,15 @@ impl NymMessage { NymMessage::Reply(_) => ReplySurbKeyDigestAlgorithm::output_size(), }; + let packet_type = PacketType::from(packet_size); + // each packet will contain an ack + variant specific data (as described above) - packet_size.plaintext_size() - ACK_OVERHEAD - variant_overhead + match packet_type { + PacketType::Outfox => { + packet_size.plaintext_size() - OUTFOX_ACK_OVERHEAD - variant_overhead + } + _ => packet_size.plaintext_size() - ACK_OVERHEAD - variant_overhead, + } } /// Length of the actual (from the **message** point of view) data that is available in each packet. diff --git a/common/nymsphinx/src/preparer/mod.rs b/common/nymsphinx/src/preparer/mod.rs index e06a9f44b9..2a9bca6159 100644 --- a/common/nymsphinx/src/preparer/mod.rs +++ b/common/nymsphinx/src/preparer/mod.rs @@ -1,8 +1,8 @@ // Copyright 2021-2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::message::{NymMessage, ACK_OVERHEAD}; -use crate::NymsphinxPayloadBuilder; +use crate::message::{NymMessage, ACK_OVERHEAD, OUTFOX_ACK_OVERHEAD}; +use crate::NymPayloadBuilder; use nym_crypto::asymmetric::encryption; use nym_crypto::Digest; use nym_sphinx_acknowledgements::surb_ack::SurbAck; @@ -13,9 +13,8 @@ use nym_sphinx_anonymous_replies::reply_surb::ReplySurb; use nym_sphinx_chunking::fragment::{Fragment, FragmentIdentifier}; use nym_sphinx_forwarding::packet::MixPacket; use nym_sphinx_params::packet_sizes::PacketSize; -use nym_sphinx_params::{ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS}; -use nym_sphinx_types::builder::SphinxPacketBuilder; -use nym_sphinx_types::{delays, Delay}; +use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS}; +use nym_sphinx_types::{delays, Delay, NymPacket}; use nym_topology::{NymTopology, NymTopologyError}; use rand::{CryptoRng, Rng}; use std::convert::TryFrom; @@ -77,6 +76,7 @@ pub trait FragmentPreparer { fragment_id: FragmentIdentifier, topology: &NymTopology, ack_key: &AckKey, + packet_type: PacketType, ) -> Result { let ack_delay = self.average_ack_delay(); @@ -87,6 +87,7 @@ pub trait FragmentPreparer { fragment_id.to_bytes(), ack_delay, topology, + packet_type, ) } @@ -107,15 +108,20 @@ pub trait FragmentPreparer { ack_key: &AckKey, reply_surb: ReplySurb, packet_sender: &Recipient, + packet_type: PacketType, ) -> Result { // each reply attaches the digest of the encryption key so that the recipient could // lookup correct key for decryption, let reply_overhead = ReplySurbKeyDigestAlgorithm::output_size(); - let expected_plaintext = fragment.serialized_size() + ACK_OVERHEAD + reply_overhead; + let expected_plaintext = match packet_type { + PacketType::Outfox => fragment.serialized_size() + OUTFOX_ACK_OVERHEAD + reply_overhead, + _ => fragment.serialized_size() + ACK_OVERHEAD + reply_overhead, + }; // the reason we're unwrapping (or rather 'expecting') here rather than handling the error // more gracefully is that this error should never be reached as it implies incorrect chunking - let packet_size = PacketSize::get_type_from_plaintext(expected_plaintext) + // reply packets are always Sphinx + let packet_size = PacketSize::get_type_from_plaintext(expected_plaintext, PacketType::Mix) .expect("the message has been incorrectly fragmented"); // this is not going to be accurate by any means. but that's the best estimation we can do @@ -126,24 +132,34 @@ pub trait FragmentPreparer { let fragment_identifier = fragment.fragment_identifier(); // create an ack - let surb_ack = - self.generate_surb_ack(packet_sender, fragment_identifier, topology, ack_key)?; + let surb_ack = self.generate_surb_ack( + packet_sender, + fragment_identifier, + topology, + ack_key, + packet_type, + )?; let ack_delay = surb_ack.expected_total_delay(); - let packet_payload = NymsphinxPayloadBuilder::new(fragment, surb_ack) - .build_reply(reply_surb.encryption_key()); + let packet_payload = match NymPayloadBuilder::new(fragment, surb_ack) + .build_reply(reply_surb.encryption_key()) + { + Ok(payload) => payload, + Err(_e) => return Err(NymTopologyError::PayloadBuilder), + }; // the unwrap here is fine as the failures can only originate from attempting to use invalid payload lengths // and we just very carefully constructed a (presumably) valid one - let (sphinx_packet, first_hop_address) = - reply_surb.apply_surb(packet_payload, packet_size).unwrap(); + let (sphinx_packet, first_hop_address) = reply_surb + .apply_surb(packet_payload, packet_size, packet_type) + .unwrap(); Ok(PreparedFragment { // the round-trip delay is the sum of delays of all hops on the forward route as // well as the total delay of the ack packet. // we don't know the delays inside the reply surbs so we use best-effort estimation from our poisson distribution total_delay: expected_forward_delay + ack_delay, - mix_packet: MixPacket::new(first_hop_address, sphinx_packet, Default::default()), + mix_packet: MixPacket::new(first_hop_address, sphinx_packet, packet_type), fragment_identifier, }) } @@ -172,27 +188,42 @@ pub trait FragmentPreparer { ack_key: &AckKey, packet_sender: &Recipient, packet_recipient: &Recipient, + packet_type: PacketType, ) -> Result { // each plain or repliable packet (i.e. not a reply) attaches an ephemeral public key so that the recipient // could perform diffie-hellman with its own keys followed by a kdf to re-derive // the packet encryption key let non_reply_overhead = encryption::PUBLIC_KEY_SIZE; - let expected_plaintext = fragment.serialized_size() + ACK_OVERHEAD + non_reply_overhead; + let expected_plaintext = match packet_type { + PacketType::Outfox => { + fragment.serialized_size() + OUTFOX_ACK_OVERHEAD + non_reply_overhead + } + _ => fragment.serialized_size() + ACK_OVERHEAD + non_reply_overhead, + }; // the reason we're unwrapping (or rather 'expecting') here rather than handling the error // more gracefully is that this error should never be reached as it implies incorrect chunking - let packet_size = PacketSize::get_type_from_plaintext(expected_plaintext) + let packet_size = PacketSize::get_type_from_plaintext(expected_plaintext, packet_type) .expect("the message has been incorrectly fragmented"); let fragment_identifier = fragment.fragment_identifier(); // create an ack - let surb_ack = - self.generate_surb_ack(packet_sender, fragment_identifier, topology, ack_key)?; + let surb_ack = self.generate_surb_ack( + packet_sender, + fragment_identifier, + topology, + ack_key, + packet_type, + )?; let ack_delay = surb_ack.expected_total_delay(); - let packet_payload = NymsphinxPayloadBuilder::new(fragment, surb_ack) - .build_regular(self.rng(), packet_recipient.encryption_key()); + let packet_payload = match NymPayloadBuilder::new(fragment, surb_ack) + .build_regular(self.rng(), packet_recipient.encryption_key()) + { + Ok(payload) => payload, + Err(_e) => return Err(NymTopologyError::PayloadBuilder), + }; // generate pseudorandom route for the packet let hops = self.num_mix_hops(); @@ -206,10 +237,28 @@ pub trait FragmentPreparer { // create the actual sphinx packet here. With valid route and correct payload size, // there's absolutely no reason for this call to fail. - let sphinx_packet = SphinxPacketBuilder::new() - .with_payload_size(packet_size.payload_size()) - .build_packet(packet_payload, &route, &destination, &delays) - .unwrap(); + let packet = match packet_type { + PacketType::Outfox => NymPacket::outfox_build( + packet_payload, + route.as_slice(), + &destination, + Some(packet_size.plaintext_size()), + )?, + PacketType::Mix => NymPacket::sphinx_build( + packet_size.payload_size(), + packet_payload, + &route, + &destination, + &delays, + )?, + PacketType::Vpn => NymPacket::sphinx_build( + packet_size.payload_size(), + packet_payload, + &route, + &destination, + &delays, + )?, + }; // from the previously constructed route extract the first hop let first_hop_address = @@ -220,7 +269,7 @@ pub trait FragmentPreparer { // well as the total delay of the ack packet. // note that the last hop of the packet is a gateway that does not do any delays total_delay: delays.iter().take(delays.len() - 1).sum::() + ack_delay, - mix_packet: MixPacket::new(first_hop_address, sphinx_packet, Default::default()), + mix_packet: MixPacket::new(first_hop_address, packet, packet_type), fragment_identifier, }) } @@ -317,11 +366,18 @@ where topology: &NymTopology, ack_key: &AckKey, reply_surb: ReplySurb, + packet_type: PacketType, ) -> Result { let sender = self.sender_address; ::prepare_reply_chunk_for_sending( - self, fragment, topology, ack_key, reply_surb, &sender, + self, + fragment, + topology, + ack_key, + reply_surb, + &sender, + packet_type, ) } @@ -331,6 +387,7 @@ where topology: &NymTopology, ack_key: &AckKey, packet_recipient: &Recipient, + packet_type: PacketType, ) -> Result { let sender = self.sender_address; @@ -341,6 +398,7 @@ where ack_key, &sender, packet_recipient, + packet_type, ) } @@ -350,9 +408,17 @@ where fragment_id: FragmentIdentifier, topology: &NymTopology, ack_key: &AckKey, + packet_type: PacketType, ) -> Result { let sender = self.sender_address; - ::generate_surb_ack(self, &sender, fragment_id, topology, ack_key) + ::generate_surb_ack( + self, + &sender, + fragment_id, + topology, + ack_key, + packet_type, + ) } pub fn pad_and_split_message( diff --git a/common/nymsphinx/src/preparer/payload.rs b/common/nymsphinx/src/preparer/payload.rs index 60786d3f11..5999026252 100644 --- a/common/nymsphinx/src/preparer/payload.rs +++ b/common/nymsphinx/src/preparer/payload.rs @@ -6,7 +6,7 @@ use nym_crypto::asymmetric::encryption; use nym_crypto::shared_key::new_ephemeral_shared_key; use nym_crypto::symmetric::stream_cipher; use nym_crypto::symmetric::stream_cipher::CipherKey; -use nym_sphinx_acknowledgements::surb_ack::SurbAck; +use nym_sphinx_acknowledgements::surb_ack::{SurbAck, SurbAckRecoveryError}; use nym_sphinx_anonymous_replies::SurbEncryptionKey; use nym_sphinx_chunking::fragment::Fragment; use nym_sphinx_params::{ @@ -14,25 +14,25 @@ use nym_sphinx_params::{ }; use rand::{CryptoRng, RngCore}; -pub struct NymsphinxPayloadBuilder { +pub struct NymPayloadBuilder { fragment: Fragment, surb_ack: SurbAck, } -impl NymsphinxPayloadBuilder { +impl NymPayloadBuilder { pub fn new(fragment: Fragment, surb_ack: SurbAck) -> Self { - NymsphinxPayloadBuilder { fragment, surb_ack } + NymPayloadBuilder { fragment, surb_ack } } fn build( self, packet_encryption_key: &CipherKey, variant_data: impl IntoIterator, - ) -> NymsphinxPayload + ) -> Result where C: StreamCipher + KeyIvInit, { - let (_, surb_ack_bytes) = self.surb_ack.prepare_for_sending(); + let (_, surb_ack_bytes) = self.surb_ack.prepare_for_sending()?; let mut fragment_data = self.fragment.into_bytes(); stream_cipher::encrypt_in_place::( @@ -46,16 +46,20 @@ impl NymsphinxPayloadBuilder { // where variant-specific data is as follows: // for replies it would be the digest of the encryption key used // for 'regular' messages it would be the public component used in DH later used in the KDF - NymsphinxPayload( + + Ok(NymPayload( surb_ack_bytes .into_iter() .chain(variant_data.into_iter()) .chain(fragment_data.into_iter()) .collect(), - ) + )) } - pub fn build_reply(self, packet_encryption_key: &SurbEncryptionKey) -> NymsphinxPayload { + pub fn build_reply( + self, + packet_encryption_key: &SurbEncryptionKey, + ) -> Result { let key_digest = packet_encryption_key.compute_digest(); self.build::( packet_encryption_key.inner(), @@ -67,7 +71,7 @@ impl NymsphinxPayloadBuilder { self, rng: &mut R, recipient_encryption_key: &encryption::PublicKey, - ) -> NymsphinxPayload + ) -> Result where R: RngCore + CryptoRng, { @@ -88,9 +92,9 @@ impl NymsphinxPayloadBuilder { // the actual byte data that will be put into the sphinx packet paylaod. // no more transformations are going to happen to it // TODO: use that fact for some better compile time assertions -pub struct NymsphinxPayload(Vec); +pub struct NymPayload(Vec); -impl AsRef<[u8]> for NymsphinxPayload { +impl AsRef<[u8]> for NymPayload { fn as_ref(&self) -> &[u8] { &self.0 } diff --git a/common/nymsphinx/src/receiver.rs b/common/nymsphinx/src/receiver.rs index 49af877502..631ee5eef0 100644 --- a/common/nymsphinx/src/receiver.rs +++ b/common/nymsphinx/src/receiver.rs @@ -7,8 +7,6 @@ use nym_crypto::asymmetric::encryption; use nym_crypto::shared_key::recompute_shared_key; use nym_crypto::symmetric::stream_cipher; use nym_crypto::symmetric::stream_cipher::CipherKey; -use nym_outfox::error::OutfoxError; -use nym_outfox::lion::lion_transform_decrypt; use nym_sphinx_anonymous_replies::requests::AnonymousSenderTag; use nym_sphinx_anonymous_replies::SurbEncryptionKey; use nym_sphinx_chunking::fragment::Fragment; @@ -76,49 +74,6 @@ pub enum MessageRecoveryError { #[error("Failed to recover message fragment - {0}")] FragmentRecoveryError(#[from] ChunkingError), - - #[error("Outfox: {source}")] - OutfoxRecoveryError { - #[from] - source: OutfoxError, - }, -} - -#[derive(Default)] -pub struct OutfoxMessageReceiver { - reconstructor: MessageReconstructor, -} - -impl OutfoxMessageReceiver { - pub fn new() -> Self { - Default::default() - } -} - -impl MessageReceiver for OutfoxMessageReceiver { - fn new() -> Self { - Self::default() - } - - fn reconstructor(&mut self) -> &mut MessageReconstructor { - &mut self.reconstructor - } - - fn num_mix_hops(&self) -> u8 { - DEFAULT_NUM_MIX_HOPS - } - - fn decrypt_raw_message( - &self, - message: &mut [u8], - key: &CipherKey, - ) -> Result<(), MessageRecoveryError> - where - C: StreamCipher + KeyIvInit, - { - lion_transform_decrypt(message, key)?; - Ok(()) - } } pub trait MessageReceiver { diff --git a/common/nymsphinx/types/Cargo.toml b/common/nymsphinx/types/Cargo.toml index 6be749396a..2c52ef03d9 100644 --- a/common/nymsphinx/types/Cargo.toml +++ b/common/nymsphinx/types/Cargo.toml @@ -9,6 +9,5 @@ repository = { workspace = true } [dependencies] sphinx-packet = { version = "0.1.0" } - -#[patch.crates-io] -#sphinx-packet = { path = "../../../../sphinx" } +nym-outfox = { path = "../../../nym-outfox" } +thiserror = "1" diff --git a/common/nymsphinx/types/src/lib.rs b/common/nymsphinx/types/src/lib.rs index e80268ada0..bd3063f939 100644 --- a/common/nymsphinx/types/src/lib.rs +++ b/common/nymsphinx/types/src/lib.rs @@ -1,7 +1,12 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +pub use nym_outfox::{ + constants::MIN_PACKET_SIZE, constants::MIX_PARAMS_LEN, constants::OUTFOX_PACKET_OVERHEAD, + error::OutfoxError, +}; // re-exporting types and constants available in sphinx +use nym_outfox::packet::{OutfoxPacket, OutfoxProcessedPacket}; pub use sphinx_packet::{ constants::{ self, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, MAX_PATH_LENGTH, NODE_ADDRESS_LENGTH, @@ -9,9 +14,123 @@ pub use sphinx_packet::{ }, crypto::{self, EphemeralSecret, PrivateKey, PublicKey, SharedSecret}, header::{self, delays, delays::Delay, ProcessedHeader, SphinxHeader, HEADER_SIZE}, - packet::builder::{self, DEFAULT_PAYLOAD_SIZE}, + packet::builder::DEFAULT_PAYLOAD_SIZE, payload::{Payload, PAYLOAD_OVERHEAD_SIZE}, route::{Destination, DestinationAddressBytes, Node, NodeAddressBytes, SURBIdentifier}, surb::{SURBMaterial, SURB}, - Error, ProcessedPacket, Result, SphinxPacket, + Error as SphinxError, ProcessedPacket, }; +use sphinx_packet::{SphinxPacket, SphinxPacketBuilder}; +use std::{array::TryFromSliceError, fmt}; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum NymPacketError { + #[error("Sphinx error: {0}")] + Sphinx(#[from] sphinx_packet::Error), + + #[error("Outfox error: {0}")] + Outfox(#[from] nym_outfox::error::OutfoxError), + + #[error("{0}")] + FromSlice(#[from] TryFromSliceError), +} + +#[allow(clippy::large_enum_variant)] +pub enum NymPacket { + Sphinx(SphinxPacket), + Outfox(OutfoxPacket), +} + +pub enum NymProcessedPacket { + Sphinx(ProcessedPacket), + Outfox(OutfoxProcessedPacket), +} + +impl fmt::Debug for NymPacket { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self { + NymPacket::Sphinx(packet) => f + .debug_struct("NymPacket::Sphinx") + .field("len", &packet.len()) + .finish(), + NymPacket::Outfox(packet) => f + .debug_struct("NymPacket::Outfox") + .field("len", &packet.len()) + .finish(), + } + } +} + +impl NymPacket { + pub fn sphinx_build>( + size: usize, + message: M, + route: &[Node], + destination: &Destination, + delays: &[Delay], + ) -> Result { + Ok(NymPacket::Sphinx( + SphinxPacketBuilder::new() + .with_payload_size(size) + .build_packet(message, route, destination, delays)?, + )) + } + pub fn sphinx_from_bytes(bytes: &[u8]) -> Result { + Ok(NymPacket::Sphinx(SphinxPacket::from_bytes(bytes)?)) + } + + pub fn outfox_build>( + payload: M, + route: &[Node], + destination: &Destination, + size: Option, + ) -> Result { + Ok(NymPacket::Outfox(OutfoxPacket::build( + payload, + route.try_into()?, + destination, + size, + )?)) + } + + pub fn outfox_from_bytes(bytes: &[u8]) -> Result { + Ok(NymPacket::Outfox(OutfoxPacket::try_from(bytes)?)) + } + + pub fn len(&self) -> usize { + match self { + NymPacket::Sphinx(packet) => packet.len(), + NymPacket::Outfox(packet) => packet.len(), + } + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn to_bytes(&self) -> Result, NymPacketError> { + match self { + NymPacket::Sphinx(packet) => Ok(packet.to_bytes()), + NymPacket::Outfox(packet) => Ok(packet.to_bytes()?), + } + } + + pub fn process( + self, + node_secret_key: &PrivateKey, + ) -> Result { + match self { + NymPacket::Sphinx(packet) => { + Ok(NymProcessedPacket::Sphinx(packet.process(node_secret_key)?)) + } + NymPacket::Outfox(mut packet) => { + let next_address = packet.decode_next_layer(node_secret_key)?; + Ok(NymProcessedPacket::Outfox(OutfoxProcessedPacket::new( + packet, + next_address, + ))) + } + } + } +} diff --git a/common/socks5-client-core/src/lib.rs b/common/socks5-client-core/src/lib.rs index 21c2316aa4..8564325f78 100644 --- a/common/socks5-client-core/src/lib.rs +++ b/common/socks5-client-core/src/lib.rs @@ -5,7 +5,7 @@ use crate::config::{Config, Socks5}; use crate::error::Socks5ClientCoreError; use crate::socks::{ authentication::{AuthenticationMethods, Authenticator, User}, - server::SphinxSocksServer, + server::NymSocksServer, }; use futures::channel::mpsc; use futures::StreamExt; @@ -19,6 +19,7 @@ use nym_client_core::client::replies::reply_storage::ReplyStorageBackend; use nym_client_core::config::DebugConfig; use nym_credential_storage::storage::Storage as CredentialStorage; use nym_sphinx::addressing::clients::Recipient; +use nym_sphinx::params::PacketType; use nym_task::{TaskClient, TaskManager}; use std::error::Error; @@ -64,6 +65,7 @@ where NymClient { config, storage } } + #[allow(clippy::too_many_arguments)] pub fn start_socks5_listener( socks5_config: &Socks5, debug_config: DebugConfig, @@ -72,6 +74,7 @@ where client_status: ClientState, self_address: Recipient, shutdown: TaskClient, + packet_type: PacketType, ) { info!("Starting socks5 listener..."); let auth_methods = vec![AuthenticationMethods::NoAuth as u8]; @@ -97,7 +100,7 @@ where .unwrap_or(debug_config.traffic.primary_packet_size); let authenticator = Authenticator::new(auth_methods, allowed_users); - let mut sphinx_socks = SphinxSocksServer::new( + let mut sphinx_socks = NymSocksServer::new( socks5_config.get_listening_port(), authenticator, socks5_config.get_provider_mix_address(), @@ -112,6 +115,7 @@ where socks5_config.get_per_request_surbs(), ), shutdown.clone(), + packet_type, ); nym_task::spawn_with_report_error( async move { @@ -203,12 +207,18 @@ where reply_storage_backend, ); - let mut started_client = base_builder.start_base().await?; + let packet_type = self.config.get_base().get_packet_type(); + let mut started_client = base_builder.start_base(packet_type).await?; let self_address = started_client.address; let client_input = started_client.client_input.register_producer(); let client_output = started_client.client_output.register_consumer(); let client_state = started_client.client_state; + info!( + "Running with {:?} packets", + self.config.get_base().get_packet_type() + ); + Self::start_socks5_listener( self.config.get_socks5(), *self.config.get_debug_settings(), @@ -217,6 +227,7 @@ where client_state, self_address, started_client.task_manager.subscribe(), + self.config.get_base().get_packet_type(), ); info!("Client startup finished!"); diff --git a/common/socks5-client-core/src/socks/client.rs b/common/socks5-client-core/src/socks/client.rs index d1d4b10697..ebd980a0e6 100644 --- a/common/socks5-client-core/src/socks/client.rs +++ b/common/socks5-client-core/src/socks/client.rs @@ -18,6 +18,7 @@ use nym_socks5_requests::{ }; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::params::PacketSize; +use nym_sphinx::params::PacketType; use nym_task::connections::{LaneQueueLengths, TransmissionLane}; use nym_task::TaskClient; use pin_project::pin_project; @@ -185,6 +186,7 @@ pub(crate) struct SocksClient { started_proxy: bool, lane_queue_lengths: LaneQueueLengths, shutdown_listener: TaskClient, + packet_type: Option, } impl Drop for SocksClient { @@ -213,6 +215,7 @@ impl SocksClient { self_address: &Recipient, lane_queue_lengths: LaneQueueLengths, mut shutdown_listener: TaskClient, + packet_type: Option, ) -> Self { // If this task fails and exits, we don't want to send shutdown signal shutdown_listener.mark_as_success(); @@ -233,6 +236,7 @@ impl SocksClient { started_proxy: false, lane_queue_lengths, shutdown_listener, + packet_type, } } @@ -349,6 +353,7 @@ impl SocksClient { msg.into_bytes(), self.config.connection_start_surbs, TransmissionLane::ConnectionId(self.connection_id), + self.packet_type, ); self.input_sender .send(input_message) @@ -371,6 +376,7 @@ impl SocksClient { self.service_provider, msg.into_bytes(), TransmissionLane::ConnectionId(self.connection_id), + self.packet_type, ); self.input_sender .send(input_message) @@ -408,6 +414,7 @@ impl SocksClient { let request_version = self.config.request_version(); let recipient = self.service_provider; + let packet_type = self.packet_type; let (stream, _) = ProxyRunner::new( stream, local_stream_remote, @@ -439,9 +446,15 @@ impl SocksClient { provider_message.into_bytes(), per_request_surbs, lane, + packet_type, ) } else { - InputMessage::new_regular(recipient, provider_message.into_bytes(), lane) + InputMessage::new_regular( + recipient, + provider_message.into_bytes(), + lane, + packet_type, + ) } }) .await diff --git a/common/socks5-client-core/src/socks/server.rs b/common/socks5-client-core/src/socks/server.rs index 179b78cca5..1fd5703113 100644 --- a/common/socks5-client-core/src/socks/server.rs +++ b/common/socks5-client-core/src/socks/server.rs @@ -10,6 +10,7 @@ use nym_client_core::client::{ }; use nym_socks5_proxy_helpers::connection_controller::Controller; use nym_sphinx::addressing::clients::Recipient; +use nym_sphinx::params::PacketType; use nym_task::connections::{ConnectionCommandSender, LaneQueueLengths}; use nym_task::TaskClient; use std::net::SocketAddr; @@ -17,7 +18,7 @@ use tap::TapFallible; use tokio::net::TcpListener; /// A Socks5 server that listens for connections. -pub struct SphinxSocksServer { +pub struct NymSocksServer { authenticator: Authenticator, listening_address: SocketAddr, service_provider: Recipient, @@ -25,10 +26,12 @@ pub struct SphinxSocksServer { client_config: client::Config, lane_queue_lengths: LaneQueueLengths, shutdown: TaskClient, + packet_type: PacketType, } -impl SphinxSocksServer { +impl NymSocksServer { /// Create a new SphinxSocks instance + #[allow(clippy::too_many_arguments)] pub(crate) fn new( port: u16, authenticator: Authenticator, @@ -37,12 +40,13 @@ impl SphinxSocksServer { lane_queue_lengths: LaneQueueLengths, client_config: client::Config, shutdown: TaskClient, + packet_type: PacketType, ) -> Self { // hardcode ip as we (presumably) ONLY want to listen locally. If we change it, we can // just modify the config let ip = "127.0.0.1"; info!("Listening on {}:{}", ip, port); - SphinxSocksServer { + NymSocksServer { authenticator, listening_address: format!("{ip}:{port}").parse().unwrap(), service_provider, @@ -50,6 +54,7 @@ impl SphinxSocksServer { client_config, lane_queue_lengths, shutdown, + packet_type, } } @@ -104,6 +109,7 @@ impl SphinxSocksServer { &self.self_address, self.lane_queue_lengths.clone(), self.shutdown.clone(), + Some(self.packet_type) ); tokio::spawn(async move { @@ -119,8 +125,8 @@ impl SphinxSocksServer { }); }, _ = self.shutdown.recv() => { - log::trace!("SphinxSocksServer: Received shutdown"); - log::debug!("SphinxSocksServer: Exiting"); + log::trace!("NymSocksServer: Received shutdown"); + log::debug!("NymSocksServer: Exiting"); return Ok(()); } } diff --git a/common/topology/src/error.rs b/common/topology/src/error.rs index 170bb1889c..bb36b42886 100644 --- a/common/topology/src/error.rs +++ b/common/topology/src/error.rs @@ -1,10 +1,13 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use std::array::TryFromSliceError; + use crate::MixLayer; +use nym_sphinx_types::NymPacketError; use thiserror::Error; -#[derive(Debug, Clone, Error)] +#[derive(Debug, Error)] pub enum NymTopologyError { #[error("The provided network topology is empty - there are no mixnodes and no gateways on it - the network request(s) probably failed")] EmptyNetworkTopology, @@ -33,4 +36,16 @@ pub enum NymTopologyError { total_nodes: usize, layer_distribution: Vec<(MixLayer, usize)>, }, + // We can't import SurbAckRecoveryError due to cyclic dependency, this is a bit dirty + #[error("Could not build payload")] + PayloadBuilder, + + #[error("Outfox: {0}")] + Outfox(#[from] nym_sphinx_types::OutfoxError), + + #[error("{0}")] + FromSlice(#[from] TryFromSliceError), + + #[error("{0}")] + PacketError(#[from] NymPacketError), } diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 7eb0a02fa0..9d5a595567 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -2,6 +2,16 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array 0.14.6", +] + [[package]] name = "aes" version = "0.7.5" @@ -9,7 +19,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ "cfg-if", - "cipher", + "cipher 0.3.0", "cpufeatures", "ctr", "opaque-debug 0.3.0", @@ -38,6 +48,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "autocfg" version = "1.1.0" @@ -86,6 +102,20 @@ dependencies = [ "opaque-debug 0.2.3", ] +[[package]] +name = "blake3" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -95,6 +125,15 @@ dependencies = [ "generic-array 0.14.6", ] +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.6", +] + [[package]] name = "bs58" version = "0.4.0" @@ -150,6 +189,30 @@ dependencies = [ "keystream", ] +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher 0.4.4", + "poly1305", + "zeroize", +] + [[package]] name = "cipher" version = "0.3.0" @@ -159,6 +222,17 @@ dependencies = [ "generic-array 0.14.6", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + [[package]] name = "coconut-test" version = "0.1.0" @@ -190,6 +264,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +[[package]] +name = "constant_time_eq" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" + [[package]] name = "cosmwasm-crypto" version = "1.0.0" @@ -258,6 +338,49 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +dependencies = [ + "cfg-if", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -276,6 +399,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.6", + "rand_core 0.6.4", + "typenum", +] + [[package]] name = "crypto-mac" version = "0.7.0" @@ -302,7 +436,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" dependencies = [ - "cipher", + "cipher 0.3.0", ] [[package]] @@ -501,6 +635,17 @@ dependencies = [ "generic-array 0.14.6", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle 2.4.1", +] + [[package]] name = "dyn-clone" version = "1.0.11" @@ -796,8 +941,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -845,6 +992,15 @@ dependencies = [ "ahash", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.1" @@ -903,6 +1059,15 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.6", +] + [[package]] name = "instant" version = "0.1.12" @@ -918,7 +1083,7 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.1", "libc", "windows-sys 0.48.0", ] @@ -1050,6 +1215,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + [[package]] name = "mixnet-vesting-integration-tests" version = "0.1.0" @@ -1076,6 +1250,16 @@ dependencies = [ "libm", ] +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + [[package]] name = "nym-coconut-bandwidth" version = "0.1.0" @@ -1252,6 +1436,23 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-outfox" +version = "0.1.0" +dependencies = [ + "blake3", + "chacha20", + "chacha20poly1305", + "curve25519-dalek", + "getrandom 0.2.8", + "log", + "rand 0.7.3", + "rayon", + "sphinx-packet", + "thiserror", + "zeroize", +] + [[package]] name = "nym-pemstore" version = "0.2.0" @@ -1291,7 +1492,9 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ + "nym-outfox", "sphinx-packet", + "thiserror", ] [[package]] @@ -1392,6 +1595,17 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1550,6 +1764,28 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1682,6 +1918,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "sec1" version = "0.2.1" @@ -1769,7 +2011,7 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if", "cpufeatures", "digest 0.9.0", @@ -1992,6 +2234,16 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle 2.4.1", +] + [[package]] name = "url" version = "2.3.1" diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index 0685c0d473..3683144980 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -5,6 +5,7 @@ use crate::authentication::encrypted_address::EncryptedAddressBytes; use crate::iv::IV; use crate::registration::handshake::SharedKeys; use crate::{GatewayMacSize, PROTOCOL_VERSION}; +use log::error; use nym_coconut_interface::Credential; use nym_crypto::generic_array::typenum::Unsigned; use nym_crypto::hmac::recompute_keyed_hmac_and_verify_tag; @@ -290,7 +291,13 @@ impl BinaryRequest { pub fn into_encrypted_tagged_bytes(self, shared_key: &SharedKeys) -> Vec { match self { BinaryRequest::ForwardSphinx(mix_packet) => { - let forwarding_data = mix_packet.into_bytes(); + let forwarding_data = match mix_packet.into_bytes() { + Ok(mix_packet) => mix_packet, + Err(e) => { + error!("Could not convert packet to bytes: {e}"); + return vec![]; + } + }; // TODO: it could be theoretically slightly more efficient if the data wasn't taken // by reference because then it makes a copy for encryption rather than do it in place diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index dfc4ae377a..1a41937c4b 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -283,7 +283,7 @@ where &self, mix_packet: MixPacket, ) -> Result { - let consumed_bandwidth = mix_packet.sphinx_packet().len() as i64; + let consumed_bandwidth = mix_packet.packet().len() as i64; let available_bandwidth = self.get_available_bandwidth().await?; @@ -309,7 +309,10 @@ where async fn handle_binary(&self, bin_msg: Vec) -> Message { // this function decrypts the request and checks the MAC match BinaryRequest::try_from_encrypted_tagged_bytes(bin_msg, &self.client.shared_keys) { - Err(e) => RequestHandlingError::InvalidBinaryRequest(e).into_error_message(), + Err(e) => { + error!("{e}"); + RequestHandlingError::InvalidBinaryRequest(e).into_error_message() + } Ok(request) => match request { // currently only a single type exists BinaryRequest::ForwardSphinx(mix_packet) => self diff --git a/gateway/src/node/mixnet_handling/receiver/connection_handler.rs b/gateway/src/node/mixnet_handling/receiver/connection_handler.rs index 148dbc2579..dd2bc5d402 100644 --- a/gateway/src/node/mixnet_handling/receiver/connection_handler.rs +++ b/gateway/src/node/mixnet_handling/receiver/connection_handler.rs @@ -11,8 +11,8 @@ use log::*; use nym_mixnet_client::forwarder::MixForwardingSender; use nym_mixnode_common::packet_processor::processor::ProcessedFinalHop; use nym_sphinx::forwarding::packet::MixPacket; -use nym_sphinx::framing::codec::SphinxCodec; -use nym_sphinx::framing::packet::FramedSphinxPacket; +use nym_sphinx::framing::codec::NymCodec; +use nym_sphinx::framing::packet::FramedNymPacket; use nym_sphinx::DestinationAddressBytes; use nym_task::TaskClient; use std::collections::HashMap; @@ -155,7 +155,7 @@ impl ConnectionHandler { self.forward_ack(forward_ack, client_address); } - async fn handle_received_packet(&mut self, framed_sphinx_packet: FramedSphinxPacket) { + async fn handle_received_packet(&mut self, framed_sphinx_packet: FramedNymPacket) { // // TODO: here be replay attack detection - it will require similar key cache to the one in // packet processor for vpn packets, @@ -182,7 +182,7 @@ impl ConnectionHandler { ) { debug!("Starting connection handler for {:?}", remote); shutdown.mark_as_success(); - let mut framed_conn = Framed::new(conn, SphinxCodec); + let mut framed_conn = Framed::new(conn, NymCodec); while !shutdown.is_shutdown() { tokio::select! { biased; diff --git a/gateway/src/node/mixnet_handling/receiver/packet_processing.rs b/gateway/src/node/mixnet_handling/receiver/packet_processing.rs index cf5e5e8e18..e7416c415c 100644 --- a/gateway/src/node/mixnet_handling/receiver/packet_processing.rs +++ b/gateway/src/node/mixnet_handling/receiver/packet_processing.rs @@ -5,7 +5,7 @@ use nym_crypto::asymmetric::encryption; use nym_mixnode_common::packet_processor::error::MixProcessingError; pub use nym_mixnode_common::packet_processor::processor::MixProcessingResult; use nym_mixnode_common::packet_processor::processor::{ProcessedFinalHop, SphinxPacketProcessor}; -use nym_sphinx::framing::packet::FramedSphinxPacket; +use nym_sphinx::framing::packet::FramedNymPacket; use thiserror::Error; #[derive(Error, Debug)] @@ -32,7 +32,7 @@ impl PacketProcessor { pub(crate) fn process_received( &self, - received: FramedSphinxPacket, + received: FramedNymPacket, ) -> Result { match self.inner_processor.process_received(received)? { MixProcessingResult::ForwardHop(..) => { diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 5f3da88b7f..ca509fdb42 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -51,6 +51,7 @@ nym-mixnet-client = { path = "../common/client-libs/mixnet-client" } nym-mixnode-common = { path = "../common/mixnode-common" } nym-nonexhaustive-delayqueue = { path = "../common/nonexhaustive-delayqueue" } nym-sphinx = { path = "../common/nymsphinx" } +nym-sphinx-params = { path = "../common/nymsphinx/params" } nym-pemstore = { path = "../common/pemstore", version = "0.2.0" } nym-task = { path = "../common/task" } nym-types = { path = "../common/types" } diff --git a/mixnode/src/main.rs b/mixnode/src/main.rs index 066d4a061e..b0cb340634 100644 --- a/mixnode/src/main.rs +++ b/mixnode/src/main.rs @@ -51,9 +51,14 @@ fn test_function() { async fn main() { cfg_if::cfg_if! { if #[cfg(feature = "cpucycles")] { - setup_tracing!("/tmp/tracing.log"); + let home_dir = dirs::home_dir().expect("Could not get $HOME"); + let logs_dir = home_dir.join(".nym").join("logs"); + let logs_dir_str = logs_dir.to_str().expect("Could not construct logs path"); + setup_tracing!(logs_dir_str); + info!("CPU cycles measurement is ON") } else { setup_logging(); + info!("CPU cycles measurement is OFF") } } diff --git a/mixnode/src/node/listener/connection_handler/mod.rs b/mixnode/src/node/listener/connection_handler/mod.rs index ed08d8c407..733d2660f8 100644 --- a/mixnode/src/node/listener/connection_handler/mod.rs +++ b/mixnode/src/node/listener/connection_handler/mod.rs @@ -9,8 +9,8 @@ use crate::node::TaskClient; use futures::StreamExt; use nym_mixnode_common::measure; use nym_sphinx::forwarding::packet::MixPacket; -use nym_sphinx::framing::codec::SphinxCodec; -use nym_sphinx::framing::packet::FramedSphinxPacket; +use nym_sphinx::framing::codec::NymCodec; +use nym_sphinx::framing::packet::FramedNymPacket; use nym_sphinx::Delay as SphinxDelay; use std::net::SocketAddr; use tokio::net::TcpStream; @@ -54,7 +54,7 @@ impl ConnectionHandler { feature = "cpucycles", instrument(skip(self, framed_sphinx_packet), fields(cpucycles)) )] - fn handle_received_packet(&self, framed_sphinx_packet: FramedSphinxPacket) { + fn handle_received_packet(&self, framed_sphinx_packet: FramedNymPacket) { // // TODO: here be replay attack detection - it will require similar key cache to the one in // packet processor for vpn packets, @@ -86,7 +86,7 @@ impl ConnectionHandler { ) { debug!("Starting connection handler for {:?}", remote); shutdown.mark_as_success(); - let mut framed_conn = Framed::new(conn, SphinxCodec); + let mut framed_conn = Framed::new(conn, NymCodec); while !shutdown.is_shutdown() { tokio::select! { biased; @@ -108,7 +108,7 @@ impl ConnectionHandler { } Some(Err(err)) => { error!( - "The socket connection got corrupted with error: {err}. Closing the socket", + "{remote:?} - The socket connection got corrupted with error: {err}. Closing the socket", ); return; } diff --git a/mixnode/src/node/listener/connection_handler/packet_processing.rs b/mixnode/src/node/listener/connection_handler/packet_processing.rs index 9ecf8ad435..1d52602b1d 100644 --- a/mixnode/src/node/listener/connection_handler/packet_processing.rs +++ b/mixnode/src/node/listener/connection_handler/packet_processing.rs @@ -6,7 +6,7 @@ use nym_crypto::asymmetric::encryption; use nym_mixnode_common::packet_processor::error::MixProcessingError; pub use nym_mixnode_common::packet_processor::processor::MixProcessingResult; use nym_mixnode_common::packet_processor::processor::SphinxPacketProcessor; -use nym_sphinx::framing::packet::FramedSphinxPacket; +use nym_sphinx::framing::packet::FramedNymPacket; // PacketProcessor contains all data required to correctly unwrap and forward sphinx packets #[derive(Clone)] @@ -31,7 +31,7 @@ impl PacketProcessor { pub(crate) fn process_received( &self, - received: FramedSphinxPacket, + received: FramedNymPacket, ) -> Result { self.node_stats_update_sender.report_received(); self.inner_processor.process_received(received) diff --git a/mixnode/src/node/packet_delayforwarder.rs b/mixnode/src/node/packet_delayforwarder.rs index 41a3e7e0fa..0e7abfa793 100644 --- a/mixnode/src/node/packet_delayforwarder.rs +++ b/mixnode/src/node/packet_delayforwarder.rs @@ -58,12 +58,12 @@ where fn forward_packet(&mut self, packet: MixPacket) { let next_hop = packet.next_hop(); - let packet_mode = packet.packet_mode(); - let sphinx_packet = packet.into_sphinx_packet(); + let packet_type = packet.packet_type(); + let packet = packet.into_packet(); - if let Err(err) = - self.mixnet_client - .send_without_response(next_hop, sphinx_packet, packet_mode) + if let Err(err) = self + .mixnet_client + .send_without_response(next_hop, packet, packet_type) { if err.kind() == io::ErrorKind::WouldBlock { // we only know for sure if we dropped a packet if our sending queue was full @@ -134,38 +134,38 @@ mod tests { use std::sync::{Arc, Mutex}; use std::time::Duration; + use nym_sphinx::NymPacket; use nym_task::TaskManager; use nym_sphinx::addressing::nodes::NymNodeRoutingAddress; use nym_sphinx_params::packet_sizes::PacketSize; - use nym_sphinx_params::PacketMode; - use nym_sphinx_types::builder::SphinxPacketBuilder; + use nym_sphinx_params::PacketType; use nym_sphinx_types::{ crypto, Delay as SphinxDelay, Destination, DestinationAddressBytes, Node, NodeAddressBytes, - SphinxPacket, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, NODE_ADDRESS_LENGTH, + DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, NODE_ADDRESS_LENGTH, }; #[derive(Default)] struct TestClient { - pub packets_sent: Arc>>, + pub packets_sent: Arc>>, } impl nym_mixnet_client::SendWithoutResponse for TestClient { fn send_without_response( &mut self, address: NymNodeRoutingAddress, - packet: SphinxPacket, - packet_mode: PacketMode, + packet: NymPacket, + packet_type: PacketType, ) -> io::Result<()> { self.packets_sent .lock() .unwrap() - .push((address, packet, packet_mode)); + .push((address, packet, packet_type)); Ok(()) } } - fn make_valid_sphinx_packet(size: PacketSize) -> SphinxPacket { + fn make_valid_sphinx_packet(size: PacketSize) -> NymPacket { let (_, node1_pk) = crypto::keygen(); let node1 = Node::new( NodeAddressBytes::from_bytes([5u8; NODE_ADDRESS_LENGTH]), @@ -192,12 +192,45 @@ mod tests { SphinxDelay::new_from_nanos(42), SphinxDelay::new_from_nanos(42), ]; - SphinxPacketBuilder::new() - .with_payload_size(size.payload_size()) - .build_packet(b"foomp", &route, &destination, &delays) + NymPacket::sphinx_build(size.payload_size(), b"foomp", &route, &destination, &delays) .unwrap() } + fn make_valid_outfox_packet(size: PacketSize) -> NymPacket { + let (_, node1_pk) = crypto::keygen(); + let node1 = Node::new( + NodeAddressBytes::from_bytes([5u8; NODE_ADDRESS_LENGTH]), + node1_pk, + ); + let (_, node2_pk) = crypto::keygen(); + let node2 = Node::new( + NodeAddressBytes::from_bytes([4u8; NODE_ADDRESS_LENGTH]), + node2_pk, + ); + let (_, node3_pk) = crypto::keygen(); + let node3 = Node::new( + NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]), + node3_pk, + ); + + let (_, node4_pk) = crypto::keygen(); + let node4 = Node::new( + NodeAddressBytes::from_bytes([2u8; NODE_ADDRESS_LENGTH]), + node4_pk, + ); + + let destination = Destination::new( + DestinationAddressBytes::from_bytes([3u8; DESTINATION_ADDRESS_LENGTH]), + [4u8; IDENTIFIER_LENGTH], + ); + + let route = &[node1, node2, node3, node4]; + + let payload = vec![1; 48]; + + NymPacket::outfox_build(payload, route, &destination, Some(size.plaintext_size())).unwrap() + } + #[tokio::test] async fn packets_received_are_forwarded() { // Wire up the DelayForwarder @@ -219,7 +252,50 @@ mod tests { let mix_packet = MixPacket::new( next_hop, make_valid_sphinx_packet(PacketSize::default()), - PacketMode::default(), + PacketType::default(), + ); + let forward_instant = None; + packet_sender + .unbounded_send((mix_packet, forward_instant)) + .unwrap(); + + // Give the the worker a chance to act + tokio::time::sleep(Duration::from_millis(10)).await; + + // The client should have forwarded the packet straight away + assert_eq!( + client_packets_sent + .lock() + .unwrap() + .iter() + .map(|(a, _, _)| *a) + .collect::>(), + vec![next_hop] + ); + } + + #[tokio::test] + async fn outfox_packets_received_are_forwarded() { + // Wire up the DelayForwarder + let (stats_sender, _stats_receiver) = mpsc::unbounded(); + let node_stats_update_sender = UpdateSender::new(stats_sender); + let client = TestClient::default(); + let client_packets_sent = client.packets_sent.clone(); + let shutdown = TaskManager::default(); + let mut delay_forwarder = + DelayForwarder::new(client, node_stats_update_sender, shutdown.subscribe()); + let packet_sender = delay_forwarder.sender(); + + // Spawn the worker, listening on packet_sender channel + tokio::spawn(async move { delay_forwarder.run().await }); + + // Send a `MixPacket` down the channel without any delay attached. + let next_hop = + NymNodeRoutingAddress::from(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)), 42)); + let mix_packet = MixPacket::new( + next_hop, + make_valid_outfox_packet(PacketSize::default()), + PacketType::default(), ); let forward_instant = None; packet_sender diff --git a/nym-api/src/network_monitor/chunker.rs b/nym-api/src/network_monitor/chunker.rs new file mode 100644 index 0000000000..1e1f4d0d4d --- /dev/null +++ b/nym-api/src/network_monitor/chunker.rs @@ -0,0 +1,86 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use nym_sphinx::forwarding::packet::MixPacket; +use nym_sphinx::message::NymMessage; +use nym_sphinx::params::{PacketSize, PacketType}; +use nym_sphinx::{ + acknowledgements::AckKey, addressing::clients::Recipient, preparer::MessagePreparer, +}; +use nym_topology::NymTopology; +use rand_07::rngs::OsRng; +use std::time::Duration; + +const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(200); +const DEFAULT_AVERAGE_ACK_DELAY: Duration = Duration::from_millis(200); + +#[derive(Clone)] +pub(crate) struct Chunker { + rng: OsRng, + packet_size: PacketSize, + message_preparer: MessagePreparer, +} + +impl Chunker { + pub(crate) fn new(tested_mix_me: Recipient) -> Self { + Chunker { + rng: OsRng, + // no point in using anything else for monitoring + // unless we should make it variable so mixnodes wouldn't know if + // non-default packet is for measurement or not + packet_size: PacketSize::RegularPacket, + message_preparer: MessagePreparer::new( + OsRng, + tested_mix_me, + DEFAULT_AVERAGE_PACKET_DELAY, + DEFAULT_AVERAGE_ACK_DELAY, + ), + } + } + + pub(crate) fn prepare_packets_from( + &mut self, + message: Vec, + topology: &NymTopology, + packet_sender: Recipient, + packet_type: PacketType, + ) -> Vec { + // I really dislike how we have to overwrite the parameter of the `MessagePreparer` on each run + // but without some significant API changes in the `MessagePreparer` this was the easiest + // way to being able to have variable sender address. + self.message_preparer.set_sender_address(packet_sender); + self.prepare_packets(message, topology, packet_sender, packet_type) + } + + fn prepare_packets( + &mut self, + message: Vec, + topology: &NymTopology, + packet_sender: Recipient, + packet_type: PacketType, + ) -> Vec { + let ack_key: AckKey = AckKey::new(&mut self.rng); + + let split_message = self + .message_preparer + .pad_and_split_message(NymMessage::new_plain(message), self.packet_size); + + let mut mix_packets = Vec::with_capacity(split_message.len()); + for message_chunk in split_message { + // don't bother with acks etc. for time being + let prepared_fragment = self + .message_preparer + .prepare_chunk_for_sending( + message_chunk, + topology, + &ack_key, + &packet_sender, + packet_type, + ) + .unwrap(); + + mix_packets.push(prepared_fragment.mix_packet); + } + mix_packets + } +} diff --git a/nym-api/src/network_monitor/mod.rs b/nym-api/src/network_monitor/mod.rs index 03e4ea65e8..a42fd3b49b 100644 --- a/nym-api/src/network_monitor/mod.rs +++ b/nym-api/src/network_monitor/mod.rs @@ -21,6 +21,7 @@ use nym_bandwidth_controller::BandwidthController; use nym_credential_storage::persistent_storage::PersistentStorage; use nym_crypto::asymmetric::{encryption, identity}; use nym_sphinx::acknowledgements::AckKey; +use nym_sphinx::params::PacketType; use nym_sphinx::receiver::MessageReceiver; use nym_task::TaskManager; use std::sync::Arc; @@ -129,6 +130,7 @@ impl<'a> NetworkMonitorBuilder<'a> { received_processor, summary_producer, self.node_status_storage, + PacketType::Mix, ); NetworkMonitorRunnables { diff --git a/nym-api/src/network_monitor/monitor/mod.rs b/nym-api/src/network_monitor/monitor/mod.rs index e3a774b166..77e48634d5 100644 --- a/nym-api/src/network_monitor/monitor/mod.rs +++ b/nym-api/src/network_monitor/monitor/mod.rs @@ -10,6 +10,7 @@ use crate::network_monitor::test_route::TestRoute; use crate::storage::NymApiStorage; use crate::support::config::Config; use log::{debug, error, info}; +use nym_sphinx::params::PacketType; use nym_sphinx::receiver::MessageReceiver; use nym_task::TaskClient; use std::collections::{HashMap, HashSet}; @@ -44,6 +45,8 @@ pub(super) struct Monitor { /// The minimum number of test routes that need to be constructed (and working) in order for /// a monitor test run to be valid. minimum_test_routes: usize, + + packet_type: PacketType, } impl Monitor { @@ -54,6 +57,7 @@ impl Monitor { received_processor: ReceivedProcessor, summary_producer: SummaryProducer, node_status_storage: NymApiStorage, + packet_type: PacketType, ) -> Self { Monitor { test_nonce: 1, @@ -68,6 +72,7 @@ impl Monitor { route_test_packets: config.get_route_test_packets(), test_routes: config.get_test_routes(), minimum_test_routes: config.get_minimum_test_routes(), + packet_type, } } @@ -125,8 +130,11 @@ impl Monitor { for route in routes { let mut packet_preparer = self.packet_preparer.clone(); let route = route.clone(); - let gateway_packets = packet_preparer - .prepare_test_route_viability_packets(&route, self.route_test_packets); + let gateway_packets = packet_preparer.prepare_test_route_viability_packets( + &route, + self.route_test_packets, + self.packet_type, + ); packets.push(gateway_packets); } @@ -233,7 +241,7 @@ impl Monitor { info!("Generating test mix packets for all the network nodes..."); let prepared_packets = self .packet_preparer - .prepare_test_packets(self.test_nonce, routes) + .prepare_test_packets(self.test_nonce, routes, self.packet_type) .await; let total_sent = prepared_packets diff --git a/nym-api/src/network_monitor/monitor/preparer.rs b/nym-api/src/network_monitor/monitor/preparer.rs index 7343a06a6e..b873669f99 100644 --- a/nym-api/src/network_monitor/monitor/preparer.rs +++ b/nym-api/src/network_monitor/monitor/preparer.rs @@ -12,7 +12,7 @@ use nym_node_tester_utils::NodeTester; use nym_sphinx::acknowledgements::AckKey; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::forwarding::packet::MixPacket; -use nym_sphinx::params::PacketSize; +use nym_sphinx::params::{PacketSize, PacketType}; use nym_topology::{gateway, mix}; use rand_07::{rngs::ThreadRng, seq::SliceRandom, thread_rng, Rng}; use std::collections::{HashMap, HashSet}; @@ -290,6 +290,8 @@ impl PacketPreparer { &mut self, route: &TestRoute, num: usize, + // TODO: Maybe do this + _packet_type: PacketType, ) -> GatewayPackets { let mut tester = self.ephemeral_mix_tester(route); let topology = route.topology(); @@ -359,6 +361,8 @@ impl PacketPreparer { &mut self, test_nonce: u64, test_routes: &[TestRoute], + // TODO: Maybe do this + _packet_type: PacketType, ) -> PreparedPackets { // only test mixnodes that are rewarded, i.e. that will be rewarded in this interval. // (remember that "idle" nodes are still part of that set) diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 3e02e639d5..ef860d020f 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3563,8 +3563,10 @@ dependencies = [ "chacha20poly1305", "curve25519-dalek", "getrandom 0.2.8", + "log", + "rand 0.7.3", "rayon", - "sphinx-packet 0.1.0 (git+https://github.com/nymtech/sphinx.git)", + "sphinx-packet", "thiserror", "zeroize", ] @@ -3655,7 +3657,6 @@ version = "0.1.0" dependencies = [ "log", "nym-crypto", - "nym-outfox", "nym-sphinx-acknowledgements", "nym-sphinx-addressing", "nym-sphinx-anonymous-replies", @@ -3750,6 +3751,7 @@ dependencies = [ "nym-sphinx-addressing", "nym-sphinx-params", "nym-sphinx-types", + "thiserror", ] [[package]] @@ -3786,7 +3788,9 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ - "sphinx-packet 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nym-outfox", + "sphinx-packet", + "thiserror", ] [[package]] @@ -5398,29 +5402,6 @@ dependencies = [ "subtle 2.4.1", ] -[[package]] -name = "sphinx-packet" -version = "0.1.0" -source = "git+https://github.com/nymtech/sphinx.git#ca107d94360cdf8bbfbdb12fe5320ed74f80e40c" -dependencies = [ - "aes 0.7.5", - "arrayref", - "blake2", - "bs58", - "byteorder", - "chacha", - "curve25519-dalek", - "digest 0.9.0", - "hkdf 0.11.0", - "hmac 0.11.0", - "lioness", - "log", - "rand 0.7.3", - "rand_distr", - "sha2 0.9.9", - "subtle 2.4.1", -] - [[package]] name = "spin" version = "0.5.2" diff --git a/nym-outfox/Cargo.toml b/nym-outfox/Cargo.toml index 68102b5514..8fcadb2f03 100644 --- a/nym-outfox/Cargo.toml +++ b/nym-outfox/Cargo.toml @@ -15,9 +15,9 @@ chacha20poly1305 = "0.10.1" # Need this star over here to pull in js into getrandom getrandom = { version = "*", features = ["js"] } thiserror = "1" - -sphinx-packet = { git = "https://github.com/nymtech/sphinx.git" } - +sphinx-packet = "0.1.0" +rand = "0.7.3" +log = "0.4" [dev-dependencies] criterion = "0.4" diff --git a/nym-outfox/src/constants.rs b/nym-outfox/src/constants.rs new file mode 100644 index 0000000000..7dd23fe6ae --- /dev/null +++ b/nym-outfox/src/constants.rs @@ -0,0 +1,22 @@ +pub const GROUPELEMENTBYTES: u8 = 32; +pub const TAGBYTES: u8 = 16; +pub const MIX_PARAMS_LEN: usize = DEFAULT_HOPS + 2; +pub const MIN_MESSAGE_LEN: usize = 24 * 2; +pub(crate) const CONTEXT: &str = "LIONKEYS"; +pub(crate) const TAG_LEN: usize = 24; +pub const DEFAULT_ROUTING_INFO_SIZE: u8 = 32; +pub const DEFAULT_HOPS: usize = 4; +pub const ROUTING_INFORMATION_LENGTH_BY_STAGE: [u8; DEFAULT_HOPS] = + [DEFAULT_ROUTING_INFO_SIZE; DEFAULT_HOPS]; +pub const MIN_PACKET_SIZE: usize = 48; + +pub const OUTFOX_PACKET_OVERHEAD: usize = MIX_PARAMS_LEN + + (groupelementbytes() + tagbytes() + DEFAULT_ROUTING_INFO_SIZE as usize) * DEFAULT_HOPS; + +pub const fn groupelementbytes() -> usize { + GROUPELEMENTBYTES as usize +} + +pub const fn tagbytes() -> usize { + TAGBYTES as usize +} diff --git a/nym-outfox/src/error.rs b/nym-outfox/src/error.rs index 8e8711b579..cb07bd00ce 100644 --- a/nym-outfox/src/error.rs +++ b/nym-outfox/src/error.rs @@ -1,10 +1,9 @@ -use std::array::TryFromSliceError; - -use crate::lion::MIN_MESSAGE_LEN; +use crate::constants::MIN_MESSAGE_LEN; +use crate::constants::MIX_PARAMS_LEN; use chacha20::cipher::InvalidLength; use thiserror::Error; -#[derive(Debug, Error)] +#[derive(Debug, Error, Clone)] pub enum OutfoxError { #[error("Lengths mismatch, expected: {expected}, got: {got}")] LenMismatch { expected: usize, got: usize }, @@ -20,8 +19,10 @@ pub enum OutfoxError { #[error("Message length must be greater then {MIN_MESSAGE_LEN} bytes")] InvalidMessageLength, #[error("{source}")] - TryFromSluce { + TryFromSlice { #[from] - source: TryFromSliceError, + source: std::array::TryFromSliceError, }, + #[error("Header length must be {MIX_PARAMS_LEN}, got {0}")] + InvalidHeaderLength(usize), } diff --git a/nym-outfox/src/format.rs b/nym-outfox/src/format.rs index bc961377f0..a613c55894 100644 --- a/nym-outfox/src/format.rs +++ b/nym-outfox/src/format.rs @@ -62,58 +62,85 @@ use chacha20poly1305::Tag; use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE; use curve25519_dalek::montgomery::MontgomeryPoint; use curve25519_dalek::scalar::Scalar; -use sphinx_packet::route::Node; use std::convert::TryInto; -const GROUPELEMENTBYTES: usize = 32; -const TAGBYTES: usize = 16; - use std::ops::Range; use std::u8; +use crate::constants::groupelementbytes; +use crate::constants::tagbytes; +use crate::constants::DEFAULT_HOPS; +use crate::constants::DEFAULT_ROUTING_INFO_SIZE; +use crate::constants::GROUPELEMENTBYTES; +use crate::constants::MIX_PARAMS_LEN; +use crate::constants::ROUTING_INFORMATION_LENGTH_BY_STAGE; +use crate::constants::TAGBYTES; use crate::error::OutfoxError; use crate::lion::*; +use std::convert::TryFrom; /// A structure that holds mix packet construction parameters. These incluse the length /// of the routing information at each hop, the number of hops, and the payload length. +#[derive(Eq, PartialEq, Debug)] pub struct MixCreationParameters { /// The routing length is inner first, so \[0\] is the innermost routing length, etc (in bytes) - pub routing_information_length_by_stage: Vec, + /// In our stratified topology this will always be 4 + pub routing_information_length_by_stage: [u8; DEFAULT_HOPS], /// The payload length (in bytes) - pub payload_length_bytes: usize, + pub payload_length_bytes: u16, +} + +impl TryFrom<&[u8]> for MixCreationParameters { + type Error = OutfoxError; + + fn try_from(v: &[u8]) -> Result { + if v.len() != MIX_PARAMS_LEN { + return Err(OutfoxError::InvalidHeaderLength(v.len())); + } + let (routing, payload) = v.split_at(DEFAULT_HOPS); + Ok(MixCreationParameters { + routing_information_length_by_stage: routing.try_into()?, + payload_length_bytes: u16::from_le_bytes(payload.try_into()?), + }) + } } impl MixCreationParameters { + pub fn to_bytes(&self) -> Vec { + let mut bytes = Vec::with_capacity(5); + bytes.extend_from_slice(self.routing_information_length_by_stage.as_slice()); + bytes.extend_from_slice(&self.payload_length_bytes.to_le_bytes()); + bytes + } + + pub fn payload_length_bytes(&self) -> usize { + self.payload_length_bytes as usize + } + /// Create a set of parameters for a mix packet format. - pub fn new(payload_length_bytes: usize) -> MixCreationParameters { + pub fn new(payload_length_bytes: u16) -> MixCreationParameters { MixCreationParameters { - routing_information_length_by_stage: Vec::new(), + routing_information_length_by_stage: [DEFAULT_ROUTING_INFO_SIZE; DEFAULT_HOPS], payload_length_bytes, } } - /// Add another outer layer containing some byte length of routing data. - pub fn add_outer_layer(&mut self, routing_information_length_bytes: usize) { - self.routing_information_length_by_stage - .push(routing_information_length_bytes); - } - /// The length of the buffer needed to build a packet. pub fn total_packet_length(&self) -> usize { - let mut len = self.payload_length_bytes; - for stage_len in &self.routing_information_length_by_stage { - len += stage_len + GROUPELEMENTBYTES + TAGBYTES + let mut len = self.payload_length_bytes(); + for stage_len in ROUTING_INFORMATION_LENGTH_BY_STAGE.iter() { + len += *stage_len as usize + groupelementbytes() + tagbytes() } len } /// Get the mix packet parameters for a single stage of mixing. pub fn get_stage_params(&self, layer_number: usize) -> (Range, MixStageParameters) { - assert!(layer_number < self.routing_information_length_by_stage.len()); + assert!(layer_number < ROUTING_INFORMATION_LENGTH_BY_STAGE.len()); let mut remaining_header_length_bytes = 0; - for (i, stage_len) in self.routing_information_length_by_stage.iter().enumerate() { + for (i, stage_len) in ROUTING_INFORMATION_LENGTH_BY_STAGE.iter().enumerate() { if i == layer_number { let params = MixStageParameters { routing_information_length_bytes: *stage_len, @@ -126,7 +153,7 @@ impl MixCreationParameters { return (total_size - inner_size..total_size, params); } else { - remaining_header_length_bytes += stage_len + GROUPELEMENTBYTES + TAGBYTES; + remaining_header_length_bytes += (stage_len + GROUPELEMENTBYTES + TAGBYTES) as u16; } } @@ -137,57 +164,70 @@ impl MixCreationParameters { /// A structure representing the parameters of a single stage of mixing. pub struct MixStageParameters { /// The routing information length for this stage of mixing - pub routing_information_length_bytes: usize, + pub routing_information_length_bytes: u8, /// The reamining header length for this stage of mixing - pub remaining_header_length_bytes: usize, + pub remaining_header_length_bytes: u16, /// The payload length - pub payload_length_bytes: usize, + pub payload_length_bytes: u16, } impl MixStageParameters { + pub fn routing_information_length_bytes(&self) -> usize { + self.routing_information_length_bytes as usize + } + + pub fn remaining_header_length_bytes(&self) -> usize { + self.remaining_header_length_bytes as usize + } + + pub fn payload_length_bytes(&self) -> usize { + self.payload_length_bytes as usize + } + pub fn incoming_packet_length(&self) -> usize { - GROUPELEMENTBYTES + TAGBYTES + self.outgoing_packet_length() + groupelementbytes() + tagbytes() + self.outgoing_packet_length() } pub fn outgoing_packet_length(&self) -> usize { - self.routing_information_length_bytes - + self.remaining_header_length_bytes - + self.payload_length_bytes + self.routing_information_length_bytes() + + self.remaining_header_length_bytes() + + self.payload_length_bytes() } pub fn pub_element_range(&self) -> Range { - 0..GROUPELEMENTBYTES + 0..groupelementbytes() } pub fn tag_range(&self) -> Range { - GROUPELEMENTBYTES..GROUPELEMENTBYTES + TAGBYTES + groupelementbytes()..groupelementbytes() + tagbytes() } pub fn routing_data_range(&self) -> Range { - GROUPELEMENTBYTES + TAGBYTES - ..GROUPELEMENTBYTES + TAGBYTES + self.routing_information_length_bytes + groupelementbytes() + tagbytes() + ..groupelementbytes() + tagbytes() + self.routing_information_length_bytes() } pub fn header_range(&self) -> Range { - GROUPELEMENTBYTES + TAGBYTES - ..GROUPELEMENTBYTES - + TAGBYTES - + self.routing_information_length_bytes - + self.remaining_header_length_bytes + groupelementbytes() + tagbytes() + ..groupelementbytes() + + tagbytes() + + self.routing_information_length_bytes() + + self.remaining_header_length_bytes() } pub fn payload_range(&self) -> Range { - self.incoming_packet_length() - self.payload_length_bytes..self.incoming_packet_length() + self.incoming_packet_length() - self.payload_length_bytes()..self.incoming_packet_length() } pub fn encode_mix_layer( &self, buffer: &mut [u8], user_secret_key: &[u8], - node: &Node, + node_pub_key: &[u8], + destination: &[u8; 32], ) -> Result { - let routing_data = node.address.as_bytes().to_vec(); - let mix_public_key = MontgomeryPoint(*node.pub_key.as_bytes()); + let routing_data = destination; + let mix_public_key = MontgomeryPoint(node_pub_key.try_into()?); let user_secret_key = Scalar::from_bytes_mod_order(user_secret_key.try_into()?); if buffer.len() != self.incoming_packet_length() { @@ -197,10 +237,10 @@ impl MixStageParameters { }); } - if routing_data.len() != self.routing_information_length_bytes { + if routing_data.len() != self.routing_information_length_bytes() { return Err(OutfoxError::LenMismatch { expected: routing_data.len(), - got: self.routing_information_length_bytes, + got: self.routing_information_length_bytes(), }); } @@ -208,7 +248,7 @@ impl MixStageParameters { let shared_key = user_secret_key * mix_public_key; // Copy rounting data into buffer - buffer[self.routing_data_range()].copy_from_slice(&routing_data); + buffer[self.routing_data_range()].copy_from_slice(routing_data); // Perform the AEAD let header_aead_key = ChaCha20Poly1305::new_from_slice(&shared_key.0[..])?; @@ -234,7 +274,7 @@ impl MixStageParameters { &self, buffer: &mut [u8], mix_secret_key: &[u8], - ) -> Result { + ) -> Result, OutfoxError> { // Check the length of the incoming buffer is correct. let mix_secret_key = Scalar::from_bytes_mod_order(mix_secret_key.try_into()?); @@ -266,9 +306,32 @@ impl MixStageParameters { ) .map_err(|e| OutfoxError::ChaCha20Poly1305Error(e.to_string()))?; + let routing_data = buffer[self.routing_data_range()].to_vec(); // Do a round of LION on the payload lion_transform_decrypt(&mut buffer[self.payload_range()], &shared_key.0)?; - Ok(shared_key) + Ok(routing_data) + } +} + +#[cfg(test)] +mod test { + use super::MixCreationParameters; + use std::convert::TryFrom; + + #[test] + fn test_to_bytes() { + let mix_params = MixCreationParameters::new(1024); + assert_eq!(mix_params.to_bytes(), vec![32, 32, 32, 32, 0, 4]) + } + + #[test] + fn test_from_bytes() { + let params_bytes = vec![32, 32, 32, 32, 0, 4]; + let mix_params = MixCreationParameters::new(1024); + assert_eq!( + mix_params, + MixCreationParameters::try_from(params_bytes.as_slice()).unwrap() + ) } } diff --git a/nym-outfox/src/lib.rs b/nym-outfox/src/lib.rs index 8ff0a79fcc..e10d30e846 100644 --- a/nym-outfox/src/lib.rs +++ b/nym-outfox/src/lib.rs @@ -1,3 +1,4 @@ +pub mod constants; pub mod error; pub mod format; pub mod lion; diff --git a/nym-outfox/src/lion.rs b/nym-outfox/src/lion.rs index 0503e7a304..05aaf8d361 100644 --- a/nym-outfox/src/lion.rs +++ b/nym-outfox/src/lion.rs @@ -36,12 +36,9 @@ use chacha20::XChaCha20; use chacha20::XNonce; use zeroize::Zeroize; +use crate::constants::{CONTEXT, MIN_MESSAGE_LEN, TAG_LEN}; use crate::error::OutfoxError; -pub const MIN_MESSAGE_LEN: usize = 24 * 2; -const CONTEXT: &str = "LIONKEYS"; -const TAG_LEN: usize = 24; - /// The lion transform encryption function. /// /// The `key` must be 32 bytes, and the `message` >= 48. The message is diff --git a/nym-outfox/src/packet.rs b/nym-outfox/src/packet.rs index ab17a88687..9ba4b05507 100644 --- a/nym-outfox/src/packet.rs +++ b/nym-outfox/src/packet.rs @@ -1,38 +1,143 @@ -use std::ops::Range; +use std::{ + array::TryFromSliceError, + collections::VecDeque, + convert::{TryFrom, TryInto}, + iter::FromIterator, + ops::Range, +}; use crate::{ + constants::{DEFAULT_HOPS, MIN_PACKET_SIZE, MIX_PARAMS_LEN}, error::OutfoxError, format::{MixCreationParameters, MixStageParameters}, }; -use sphinx_packet::{packet::builder::DEFAULT_PAYLOAD_SIZE, route::Node}; +use rand::{rngs::OsRng, RngCore}; +use sphinx_packet::{ + crypto::PrivateKey, + packet::builder::DEFAULT_PAYLOAD_SIZE, + route::{Destination, Node}, +}; +#[derive(Debug)] pub struct OutfoxPacket { mix_params: MixCreationParameters, payload: Vec, } -pub const DEFAULT_ROUTING_INFO_SIZE: usize = 32; +pub struct OutfoxProcessedPacket { + packet: OutfoxPacket, + next_address: [u8; 32], +} + +impl OutfoxProcessedPacket { + pub fn new(packet: OutfoxPacket, next_address: [u8; 32]) -> Self { + OutfoxProcessedPacket { + packet, + next_address, + } + } + + pub fn into_packet(self) -> OutfoxPacket { + self.packet + } + + pub fn next_address(&self) -> &[u8; 32] { + &self.next_address + } +} + +impl TryFrom<&[u8]> for OutfoxPacket { + type Error = OutfoxError; + + fn try_from(v: &[u8]) -> Result { + let (header, payload) = v.split_at(MIX_PARAMS_LEN); + Ok(OutfoxPacket { + mix_params: MixCreationParameters::try_from(header)?, + payload: payload.to_vec(), + }) + } +} impl OutfoxPacket { - pub fn build( - payload: &[u8], - route: &[Node; 3], - user_secret_key: &[u8], - ) -> Result { - let mut mix_params = MixCreationParameters::new(DEFAULT_PAYLOAD_SIZE); - - for node in route.iter() { - mix_params.add_outer_layer(node.address.as_bytes_ref().len()); + pub fn recover_plaintext(&self) -> Vec { + let plaintext = self.payload()[self.payload_range()].to_vec(); + if plaintext.starts_with(&[0]) { + let mut plaintext = VecDeque::from_iter(plaintext); + while let Some(0) = plaintext.front() { + plaintext.pop_front(); + } + return plaintext.make_contiguous().to_vec(); } + plaintext + } - let padding = mix_params.total_packet_length() - payload.len(); + pub fn len(&self) -> usize { + self.mix_params().total_packet_length() + MIX_PARAMS_LEN + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn to_bytes(&self) -> Result, OutfoxError> { + let mut bytes = vec![]; + bytes.extend(self.mix_params.to_bytes()); + bytes.extend(self.payload.as_slice()); + Ok(bytes) + } + + pub fn build>( + payload: M, + route: &[Node; 4], + destination: &Destination, + packet_size: Option, + ) -> Result { + let mut secret_key = [0; 32]; + OsRng.fill_bytes(&mut secret_key); + let packet_size = packet_size.unwrap_or(DEFAULT_PAYLOAD_SIZE); + let packet_size = if packet_size < MIN_PACKET_SIZE { + MIN_PACKET_SIZE + } else { + packet_size + }; + let mix_params = MixCreationParameters::new(packet_size as u16); + + let padding = mix_params.total_packet_length() - payload.as_ref().len(); let mut buffer = vec![0; padding]; - buffer.extend_from_slice(payload); + buffer.extend_from_slice(payload.as_ref()); - for (idx, node) in route.iter().rev().enumerate() { - let (range, stage_params) = mix_params.get_stage_params(idx); - stage_params.encode_mix_layer(&mut buffer[range], user_secret_key, node)?; + // Last node in the route is a gateway, it will decrypt last, and get the final destination address + let (range, stage_params) = mix_params.get_stage_params(0); + stage_params.encode_mix_layer( + &mut buffer[range], + &secret_key, + route.last().unwrap().pub_key.as_bytes(), + destination.address.as_bytes_ref(), + )?; + + let route = route.iter().rev().collect::>(); + + // We've reversed the route, and we iterate pairs of node, first node in the pair is the destination, and the second(last) is the processing node + // Route: [N1, N2, N3, G] + // Reverse: [G, N3, N2, N1] + // Pairs: [(G, N3), (N3, N2), (N2, N1)] + // We iterate over pairs, and encode the mix layer for each pair + // For the first pair, we encode the mix layer for N3, and the destination is G + // For the second pair, we encode the mix layer for N2, and the destination is N3 + // For the third pair, we encode the mix layer for N1, and the destination is N2 + // Entry gateway will simply forward the packet to N1 and processing will continue from there + for (idx, nodes) in route.windows(2).enumerate() { + let (range, stage_params) = mix_params.get_stage_params(idx + 1); + // We know that we'll always get 4 nodes, so we can unwrap here + let processing_node = nodes.last().unwrap(); + let destination_node = nodes.first().unwrap(); + stage_params.encode_mix_layer( + &mut buffer[range], + &secret_key, + processing_node.pub_key.as_bytes(), + destination_node.address.as_bytes_ref(), + )?; } Ok(OutfoxPacket { @@ -54,7 +159,7 @@ impl OutfoxPacket { } pub fn payload_range(&self) -> Range { - self.stage_params(2).1.payload_range() + self.stage_params(DEFAULT_HOPS - 1).1.payload_range() } pub fn payload_mut(&mut self) -> &mut [u8] { @@ -65,9 +170,52 @@ impl OutfoxPacket { &mut self, layer: usize, mix_secret_key: &[u8; 32], - ) -> Result<(), OutfoxError> { + ) -> Result, OutfoxError> { let (range, params) = self.stage_params(layer); - params.decode_mix_layer(&mut self.payload_mut()[range], mix_secret_key)?; + let routing_data = + params.decode_mix_layer(&mut self.payload_mut()[range], mix_secret_key)?; + Ok(routing_data) + } + + pub fn update_routing_information(&mut self, layer: usize) -> Result<(), TryFromSliceError> { + let mut routing_info = self + .mix_params() + .routing_information_length_by_stage + .to_vec(); + routing_info.push(0); + routing_info.swap_remove(layer); + self.mix_params.routing_information_length_by_stage = routing_info.as_slice().try_into()?; Ok(()) } + + pub fn is_final_hop(&self) -> bool { + self.mix_params() + .routing_information_length_by_stage + .iter() + .all(|x| x == &0) + } + + pub fn decode_next_layer( + &mut self, + mix_secret_key: &PrivateKey, + ) -> Result<[u8; 32], OutfoxError> { + let mix_secret_key = mix_secret_key.to_bytes(); + let routing_lenght_by_stage = self + .mix_params() + .routing_information_length_by_stage + .as_slice(); + let mut layer = DEFAULT_HOPS - 1; + for (i, length) in routing_lenght_by_stage.iter().rev().enumerate() { + if length == &32 { + layer = DEFAULT_HOPS - 1 - i; + break; + } + } + self.decode_mix_layer(layer, &mix_secret_key)?; + self.update_routing_information(layer)?; + let (range, stage_params) = self.mix_params().get_stage_params(layer); + let routing_bytes = &self.payload()[range][stage_params.routing_data_range()]; + let routing_address: [u8; 32] = routing_bytes.try_into()?; + Ok(routing_address) + } } diff --git a/nym-outfox/tests/unittests.rs b/nym-outfox/tests/unittests.rs index b085210756..ce5cdfbfa8 100644 --- a/nym-outfox/tests/unittests.rs +++ b/nym-outfox/tests/unittests.rs @@ -3,25 +3,27 @@ extern crate nym_outfox; #[cfg(test)] mod tests { - use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE; - use curve25519_dalek::scalar::Scalar; - use nym_outfox::packet::OutfoxPacket; - use sphinx_packet::constants::NODE_ADDRESS_LENGTH; - use sphinx_packet::crypto::PublicKey; - use sphinx_packet::packet::builder::DEFAULT_PAYLOAD_SIZE; - use sphinx_packet::route::Node; - use sphinx_packet::route::NodeAddressBytes; - use std::convert::TryInto; - - use nym_outfox::format::*; - use nym_outfox::lion::*; - use std::iter::repeat_with; pub fn randombytes(n: usize) -> Vec { repeat_with(|| fastrand::u8(..)).take(n).collect() } + use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE; + use curve25519_dalek::scalar::Scalar; + use nym_outfox::packet::OutfoxPacket; + use sphinx_packet::constants::NODE_ADDRESS_LENGTH; + use sphinx_packet::crypto::PublicKey; + use sphinx_packet::route::Destination; + use sphinx_packet::route::DestinationAddressBytes; + use sphinx_packet::route::Node; + use sphinx_packet::route::NodeAddressBytes; + use std::convert::TryFrom; + use std::convert::TryInto; + + use nym_outfox::format::*; + use nym_outfox::lion::*; + #[test] fn test_encode_decode() { let mix_params = MixStageParameters { @@ -37,6 +39,7 @@ mod tests { let mix_public_key = (&ED25519_BASEPOINT_TABLE * &mix_secret_scalar).to_montgomery(); let routing = [0; 32]; + let destination = [0; 32]; let buffer = randombytes(mix_params.incoming_packet_length()); @@ -48,7 +51,12 @@ mod tests { let node = Node::new(node_address_bytes, mix_public_key); let _ = mix_params - .encode_mix_layer(&mut new_buffer[..], &user_secret, &node) + .encode_mix_layer( + &mut new_buffer[..], + &user_secret, + node.pub_key.as_bytes(), + &destination, + ) .unwrap(); assert!(new_buffer[mix_params.payload_range()] != buffer[mix_params.payload_range()]); @@ -81,8 +89,6 @@ mod tests { #[test] fn test_packet_params() { - let user_secret = randombytes(32); - let (node1_pk, node1_pub) = sphinx_packet::crypto::keygen(); let node1 = Node::new( NodeAddressBytes::from_bytes([0u8; NODE_ADDRESS_LENGTH]), @@ -99,16 +105,41 @@ mod tests { node3_pub, ); - let route = [node1, node2, node3]; + let (gateway_pk, gateway_pub) = sphinx_packet::crypto::keygen(); + let gateway = Node::new( + NodeAddressBytes::from_bytes([3u8; NODE_ADDRESS_LENGTH]), + gateway_pub, + ); - let payload = randombytes(DEFAULT_PAYLOAD_SIZE); + let destination = Destination::new( + DestinationAddressBytes::from_bytes([9u8; NODE_ADDRESS_LENGTH]), + [0u8; 16], + ); - let mut packet = OutfoxPacket::build(&payload, &route, &user_secret).unwrap(); + let route = [node1, node2.clone(), node3.clone(), gateway.clone()]; - packet.decode_mix_layer(2, &node1_pk.to_bytes()).unwrap(); - packet.decode_mix_layer(1, &node2_pk.to_bytes()).unwrap(); - packet.decode_mix_layer(0, &node3_pk.to_bytes()).unwrap(); + let payload = randombytes(21); - assert_eq!(payload, &packet.payload()[packet.payload_range()]); + let packet = + OutfoxPacket::build(&payload, &route, &destination, Some(payload.len())).unwrap(); + let packet_bytes = packet.to_bytes().unwrap(); + println!( + "packet bytes length, {}, declared {}", + packet_bytes.len(), + packet.len() + ); + + let mut packet = OutfoxPacket::try_from(packet_bytes.as_slice()).unwrap(); + + let next_address = packet.decode_next_layer(&node1_pk).unwrap(); + assert_eq!(next_address, node2.address.as_bytes()); + let next_address = packet.decode_next_layer(&node2_pk).unwrap(); + assert_eq!(next_address, node3.address.as_bytes()); + let next_address = packet.decode_next_layer(&node3_pk).unwrap(); + assert_eq!(next_address, gateway.address.as_bytes()); + let destination_address = packet.decode_next_layer(&gateway_pk).unwrap(); + assert_eq!(destination_address, destination.address.as_bytes()); + + assert_eq!(payload, packet.recover_plaintext()); } } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index c5ff8448ac..98cea3eedc 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -120,6 +120,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + [[package]] name = "async-trait" version = "0.1.64" @@ -289,6 +295,20 @@ dependencies = [ "digest 0.10.6", ] +[[package]] +name = "blake3" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.6", +] + [[package]] name = "block" version = "0.1.6" @@ -497,6 +517,30 @@ dependencies = [ "keystream", ] +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher 0.4.4", + "poly1305", + "zeroize", +] + [[package]] name = "cipher" version = "0.3.0" @@ -514,6 +558,7 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", + "zeroize", ] [[package]] @@ -647,6 +692,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +[[package]] +name = "constant_time_eq" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" + [[package]] name = "convert_case" version = "0.4.0" @@ -793,6 +844,30 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.8.0", + "scopeguard", +] + [[package]] name = "crossbeam-utils" version = "0.8.14" @@ -1347,7 +1422,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" dependencies = [ - "memoffset", + "memoffset 0.6.5", "rustc_version 0.3.3", ] @@ -2588,6 +2663,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.16" @@ -2983,6 +3067,23 @@ dependencies = [ "url", ] +[[package]] +name = "nym-outfox" +version = "0.1.0" +dependencies = [ + "blake3", + "chacha20", + "chacha20poly1305", + "curve25519-dalek", + "getrandom 0.2.8", + "log", + "rand 0.7.3", + "rayon", + "sphinx-packet", + "thiserror", + "zeroize", +] + [[package]] name = "nym-pemstore" version = "0.2.0" @@ -3003,7 +3104,9 @@ dependencies = [ name = "nym-sphinx-types" version = "0.2.0" dependencies = [ + "nym-outfox", "sphinx-packet", + "thiserror", ] [[package]] @@ -3679,6 +3782,17 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + [[package]] name = "polyval" version = "0.6.0" @@ -3931,6 +4045,28 @@ dependencies = [ "cty", ] +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.16" diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 4ee8bb7a82..d0bbe86d61 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -472,7 +472,8 @@ where base_builder = base_builder.with_topology_provider(topology_provider); } - let started_client = base_builder.start_base().await?; + let packet_type = self.config.packet_type(); + let started_client = base_builder.start_base(packet_type).await?; let nym_address = started_client.address; Ok((started_client, nym_address)) @@ -509,6 +510,7 @@ where .clone() .ok_or(Error::Socks5Config { set: false })?; let debug_config = self.config.debug_config; + let packet_type = self.config.packet_type(); let (mut started_client, nym_address) = self.connect_to_mixnet_common().await?; let (socks5_status_tx, mut socks5_status_rx) = mpsc::channel(128); @@ -524,6 +526,7 @@ where client_state.clone(), nym_address, started_client.task_manager.subscribe(), + packet_type, ); started_client .task_manager @@ -588,6 +591,7 @@ where client_state, reconstructed_receiver, task_manager: started_client.task_manager, + packet_type: None, }) } } diff --git a/sdk/rust/nym-sdk/src/mixnet/config.rs b/sdk/rust/nym-sdk/src/mixnet/config.rs index 3945b7b7f3..98bf7fb2db 100644 --- a/sdk/rust/nym-sdk/src/mixnet/config.rs +++ b/sdk/rust/nym-sdk/src/mixnet/config.rs @@ -1,5 +1,6 @@ use nym_client_core::config::DebugConfig; use nym_network_defaults::NymNetworkDetails; +use nym_sphinx::params::PacketType; #[derive(Clone, Debug, Default)] pub enum KeyMode { @@ -34,4 +35,12 @@ pub struct Config { /// Flags controlling all sorts of internal client behaviour. /// Changing these risk compromising network anonymity! pub debug_config: DebugConfig, + + pub packet_type: PacketType, +} + +impl Config { + pub fn packet_type(&self) -> PacketType { + self.packet_type + } } diff --git a/sdk/rust/nym-sdk/src/mixnet/native_client.rs b/sdk/rust/nym-sdk/src/mixnet/native_client.rs index 02ec3a6389..1f6179fad8 100644 --- a/sdk/rust/nym-sdk/src/mixnet/native_client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/native_client.rs @@ -3,7 +3,8 @@ use nym_client_core::client::{ inbound_messages::InputMessage, received_buffer::ReconstructedMessagesReceiver, }; -use nym_sphinx::{addressing::clients::Recipient, receiver::ReconstructedMessage}; +use nym_sphinx::addressing::clients::Recipient; +use nym_sphinx::{params::PacketType, receiver::ReconstructedMessage}; use nym_task::{ connections::{ConnectionCommandSender, LaneQueueLengths, TransmissionLane}, TaskManager, @@ -38,6 +39,7 @@ pub struct MixnetClient { /// The task manager that controlls all the spawned tasks that the clients uses to do it's job. pub(crate) task_manager: TaskManager, + pub(crate) packet_type: Option, } impl MixnetClient { @@ -151,9 +153,11 @@ impl MixnetClient { let lane = TransmissionLane::General; let input_msg = match surbs { IncludedSurbs::Amount(surbs) => { - InputMessage::new_anonymous(address, message, surbs, lane) + InputMessage::new_anonymous(address, message, surbs, lane, self.packet_type) + } + IncludedSurbs::ExposeSelfAddress => { + InputMessage::new_regular(address, message, lane, self.packet_type) } - IncludedSurbs::ExposeSelfAddress => InputMessage::new_regular(address, message, lane), }; self.send(input_msg).await }