diff --git a/nyash_client_cpu/BUILDING.md b/nyash_client_cpu/BUILDING.md new file mode 100644 index 0000000..01bce6e --- /dev/null +++ b/nyash_client_cpu/BUILDING.md @@ -0,0 +1,154 @@ + + +Need to pass into CMD for opt +``` +RUSTFLAGS='--cfg aes_backend="avx512" -Ctarget-feature=+aes,+avx512f,+vaes' cargo build --release +``` + +``` +Passing RUSTFLAGS=-Ctarget-feature=+aes,+ssse3 explicitly at compile-time will override runtime detection and ensure that AES-NI is used or passing RUSTFLAGS=-Ctarget-feature=+aes,+avx512f,+ssse3,+vaes will ensure that AESNI and VAES are always used. +``` + + +# Building nyash_client + +Cross-compilation guide for **Ubuntu 24.04 LTS** — produces native Linux binary and Windows `.exe` from a single build server. + +## Requirements + +- Ubuntu 24.04 LTS (Noble Numbat) +- Internet access on the build server +- No GPU required — OpenCL CPU runtime is provided by the user at runtime + +--- + +## Step 1 — System packages + +```bash +sudo apt update && sudo apt install -y \ + curl wget git unzip build-essential pkg-config \ + gcc-mingw-w64-x86-64 mingw-w64 mingw-w64-tools \ + ocl-icd-opencl-dev opencl-headers pocl-opencl-icd \ + protobuf-compiler +``` + +--- + +## Step 2 — Rust + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +# Select: 1 (default) + +source $HOME/.cargo/env + +rustup target add x86_64-pc-windows-gnu +``` + +Verify: + +```bash +rustc --version +protoc --version +``` + +--- + +## Step 3 — OpenCL Windows stub + +The build server does not need a GPU or OpenCL runtime. Only a linker stub (`libOpenCL.a`) is required at compile time. The actual OpenCL runtime is provided by the user's OS/drivers at runtime. + +```bash +cd ~ +wget https://github.com/KhronosGroup/OpenCL-SDK/releases/download/v2023.12.14/OpenCL-SDK-v2023.12.14-Win-x64.zip +unzip OpenCL-SDK-v2023.12.14-Win-x64.zip -d opencl-sdk + +SDK=~/opencl-sdk/OpenCL-SDK-v2023.12.14-Win-x64 + +# Generate .def from DLL +cd $SDK/bin +gendef OpenCL.dll + +# Generate libOpenCL.a from .def +x86_64-w64-mingw32-dlltool \ + -D OpenCL.dll \ + -d OpenCL.def \ + -l libOpenCL.a + +# Install into MinGW sysroot +sudo cp libOpenCL.a /usr/x86_64-w64-mingw32/lib/ +sudo cp -r $SDK/include/CL /usr/x86_64-w64-mingw32/include/ +``` + +Verify: + +```bash +ls /usr/x86_64-w64-mingw32/lib/libOpenCL.a +ls /usr/x86_64-w64-mingw32/include/CL/cl.h +``` + +--- + +## Step 4 — Clone the repository + +```bash +cd ~ +git clone https://github.com/Nyanraltotlapun/nyash-aes-xts256-plain64.git +cd nyash-aes-xts256-plain64/nyash_client +``` + +--- + +## Step 5 — Cargo config + +Create `.cargo/config.toml` in the `nyash_client` directory: + +```bash +mkdir -p .cargo +cat > .cargo/config.toml << 'EOF' +[target.x86_64-pc-windows-gnu] +linker = "x86_64-w64-mingw32-gcc" +ar = "x86_64-w64-mingw32-ar" +rustflags = ["-L", "/usr/x86_64-w64-mingw32/lib"] + +[target.x86_64-unknown-linux-gnu] +linker = "gcc" + +[env] +PROTOC = "/usr/bin/protoc" +EOF +``` + +--- + +## Step 6 — Build + +```bash +rustup target add x86_64-pc-windows-gnu + +# Linux +cargo build --release + +# Windows +cargo build --release --target x86_64-pc-windows-gnu +``` + +--- + +## Output + +| Platform | Path | +|----------|------| +| Linux | `target/release/nyash-client` | +| Windows | `target/x86_64-pc-windows-gnu/release/nyash-client.exe` | + +--- + +## Runtime requirements for end users + +The `.exe` does **not** bundle an OpenCL runtime — it is loaded dynamically from the user's system. + +| OS | OpenCL source | +|---------|----------------------------------------------------| +| Windows | Intel CPU Runtime for OpenCL — installed automatically with Intel drivers, or download from [intel.com](https://www.intel.com/content/www/us/en/developer/articles/tool/opencl-drivers.html) | +| Linux | `sudo apt install pocl-opencl-icd` (CPU) or vendor GPU driver | diff --git a/nyash_client_cpu/Cargo.lock b/nyash_client_cpu/Cargo.lock new file mode 100644 index 0000000..a6adf21 --- /dev/null +++ b/nyash_client_cpu/Cargo.lock @@ -0,0 +1,1231 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aes" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" +dependencies = [ + "cipher", + "cpubits", + "cpufeatures", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "axum" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +dependencies = [ + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cipher" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cpubits" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" + +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a043dc74da1e37d6afe657061213aa6f425f855399a11d3463c6ecccc4dfda1f" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hybrid-array" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "libc", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.184" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mio" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "nyash_client" +version = "0.2.0" +dependencies = [ + "aes", + "prost", + "serde", + "serde_json", + "threadpool", + "tokio", + "tonic", + "tonic-prost", + "tonic-prost-build", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.5", + "indexmap", +] + +[[package]] +name = "pin-project" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +dependencies = [ + "heck", + "itertools", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "pulldown-cmark", + "pulldown-cmark-to-cmark", + "regex", + "syn", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost", +] + +[[package]] +name = "pulldown-cmark" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + +[[package]] +name = "pulldown-cmark-to-cmark" +version = "22.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90" +dependencies = [ + "pulldown-cmark", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tokio" +version = "1.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tonic" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +dependencies = [ + "async-trait", + "axum", + "base64", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project", + "socket2", + "sync_wrapper", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tonic-prost" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +dependencies = [ + "bytes", + "prost", + "tonic", +] + +[[package]] +name = "tonic-prost-build" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types", + "quote", + "syn", + "tempfile", + "tonic-build", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project-lite", + "slab", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/nyash_client_cpu/Cargo.toml b/nyash_client_cpu/Cargo.toml new file mode 100644 index 0000000..10d9571 --- /dev/null +++ b/nyash_client_cpu/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "nyash_client" +version = "0.2.0" +edition = "2024" +build = "build.rs" + +[[bin]] # Bin to run the HelloWorld gRPC client +name = "nyash-client" +path = "src/client.rs" + +[dependencies] +aes = { version = "0.9" } +prost = "0.14.3" +serde = { version = "1.0.228", features = ["derive"] } +serde_json = "1.0.149" +threadpool = "1.8.1" +tokio = { version = "1.50.0", features = ["rt", "macros", "signal"] } +tonic = "0.14.5" +tonic-prost = "0.14.5" + +[build-dependencies] +tonic-prost-build = "0.14.5" + + +[profile.release] +lto = true +codegen-units = 1 +opt-level = 3 +strip = true + + diff --git a/nyash_client_cpu/build.rs b/nyash_client_cpu/build.rs new file mode 100644 index 0000000..338a638 --- /dev/null +++ b/nyash_client_cpu/build.rs @@ -0,0 +1,26 @@ + + +fn main() -> Result<(), Box> { + //compile gRPC + tonic_prost_build::compile_protos("proto/nyash.proto")?; + + + //******************* compile ocl into spirv64 ********* + // let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + // let ocl_src_dir = Path::new(&manifest_dir).join("src/open_cl"); + // let spirv_build_script = ocl_src_dir.clone().join("build_spirv.sh"); + + + // let out_dir = env::var("OUT_DIR").unwrap(); + // let spirv_bin_path = Path::new(&out_dir).join("nyash_aes_xts256_plain.spv"); + // let str_spirv_bit_p = spirv_bin_path.to_str().expect("Error converting spirv out path to str!"); + // let _output = Command::new(spirv_build_script) + // .current_dir(ocl_src_dir) + // .arg(str_spirv_bit_p) + // .output() + // .expect("Failed to execute spirv build script!"); + + // ***************** concat ocl sources to one file and zip it ********************** + + Ok(()) +} \ No newline at end of file diff --git a/nyash_client_cpu/proto/nyash.proto b/nyash_client_cpu/proto/nyash.proto new file mode 100644 index 0000000..2772e84 --- /dev/null +++ b/nyash_client_cpu/proto/nyash.proto @@ -0,0 +1,80 @@ +syntax = "proto3"; +package nyash_proto; + +// serving key brutforcing for aes xts +service NyashLuks { + // Requesting work, gettin in response work data, error, or message that there is no work currently awaylable. + rpc RequestWork (WorkRequest) returns (WorkReply); + // Commiting work, with work ID. If key was found, sending also discowered key + rpc CommitWork (WorkCommit) returns (CommitReply); + // Request owerall key search progress + rpc RequestProgress (ProgressRequest) returns (ProgressReply); +} + +message WorkRequest { + // Request work from server + // Preffered work size in number of keys + uint64 pref_work_size = 1; +} + +message WorkReply { + oneof result { + WorkData work_data = 1; + bool no_work = 2; + string error = 3; + } +} + +message WorkData { + // work id + uint64 work_id =1; + // work size - number of keys to check + uint64 work_size= 2; + // tweak key is 128 bit. We send it as two uint64 values + uint64 tweak_key0 =3; + uint64 tweak_key1 =4; + // start key is 128 bit. We send it as two uint64 values + uint64 start_key0 =5; + uint64 start_key1 =6; +} + +message WorkCommit { + // work id + uint64 work_id =1; + oneof result { + bool no_key = 2; + KeyData found_key = 3; + } + +} + +message KeyData { + // tweak key is 128 bit. We send it as two uint64 values + uint64 tweak_key0 =3; + uint64 tweak_key1 =4; + // start key is 128 bit. We send it as two uint64 values + uint64 start_key0 =5; + uint64 start_key1 =6; +} + + +message CommitReply { + // Status code + // 0 - means ok + // 1 - something went wrong on server + // 2 - something wrong with request + uint32 status_code = 1; + // Brutforce progress as ratio from 0 to 1(completed) + double progress = 2; +} + +// request total progress +message ProgressRequest { + +} + +message ProgressReply { + // Brutforce progress as ratio from 0 to 1(completed) + bool key_found = 1; + double progress = 2; +} \ No newline at end of file diff --git a/nyash_client_cpu/src/aes_cpu.rs b/nyash_client_cpu/src/aes_cpu.rs new file mode 100644 index 0000000..1fef2d0 --- /dev/null +++ b/nyash_client_cpu/src/aes_cpu.rs @@ -0,0 +1,189 @@ +use aes; + +use aes::Aes128; +use aes::cipher::array::sizes; +use aes::cipher::{Array, BlockCipherEncrypt, KeyInit}; +use std::sync::mpsc; +use threadpool::ThreadPool; + +/// Galois field multiplication +/// Multiplies a 128-bit block by x in GF(2^128) for AES-XTS. +/// The irreducible polynomial used is x^128 + x^7 + x^2 + x + 1 (0x87). +// #[inline] +// fn gf128_mul_by_x(block: &mut Array) { +// let mut carry = 0u8; +// // Process bytes from most significant (15) to least significant (0) +// for byte in block.iter_mut().rev() { +// let temp = *byte; +// *byte = (*byte << 1) | carry; +// carry = temp >> 7; // The bit that was shifted out +// } +// // If the most significant bit of the original block was 1, apply reduction +// if carry != 0 { +// block[15] ^= 0x87; // XOR with the reduction polynomial +// } +// } + +// #[inline] +// fn aes_xts256_gen_tweak( +// tweak_key: &Array, +// sector_number: &Array, +// block_number: u32, +// tweak_buff: &mut Array, +// ) { +// let cipher = Aes128::new(tweak_key); +// cipher.encrypt_block_b2b(sector_number, tweak_buff); + +// //Double the tweak value block_n-1 times (since first block is 0) +// for _ in 0..block_number { +// gf128_mul_by_x(tweak_buff); +// } +// } + +#[inline] +fn gen_tweak_zero_block(tweak_key: &Array) -> Array { + let cipher = Aes128::new(tweak_key); + let mut res: Array = Array([0u8;16]); + cipher.encrypt_block(&mut res); + res +} + +#[inline] +fn add_one_to_block_(block: &mut Array) -> bool { + let mut carry = false; + (block[0], carry) = block[0].carrying_add(1u8, carry); + + for i in 1..16 { + if carry == false { + break; + } + (block[i], carry) = block[i].carrying_add(0u8, carry); + } + carry +} + +#[inline] +fn xor_arrays( + a_arr: &Array, + b_arr: &Array, + out_arr: &mut Array, +) { + out_arr + .iter_mut() + .zip(a_arr.iter().zip(b_arr.iter())) + .for_each(|(o, (a, b))| *o = a ^ b); +} + +#[inline] +fn xor_array_(a_arr: &mut Array, b_arr: &Array) { + a_arr + .iter_mut() + .zip(b_arr.iter()) + .for_each(|(o, a)| *o ^= a); +} + +// fn add_u64_to_arr_u8(arr: &Array, b: u64) -> Array { +// let mut res: Array = Array([0u8; 16]); +// let b_bytes = b.to_le_bytes(); +// let mut carry: bool = false; +// for i in 0..8 { +// (res[i], carry) = arr[i].carrying_add(b_bytes[i], carry); +// } + +// for i in 8..16 { +// (res[i], carry) = arr[i].carrying_add(0u8, carry); +// } + +// res +// } + +fn add_u64_to_arr_u8_(arr: &mut Array, b: u64) -> bool { + let b_bytes = b.to_le_bytes(); + let mut carry: bool = false; + for i in 0..8 { + (arr[i], carry) = arr[i].carrying_add(b_bytes[i], carry); + } + + for i in 8..16 { + (arr[i], carry) = arr[i].carrying_add(0u8, carry); + } + + carry +} + +pub fn encrypt_and_check( + start_key: &Array, + tweak: &Array, + batch_size: u64, + in_block: &Array, + search_block: &Array, +) -> Option> { + let mut current_key = start_key.clone(); + let mut out_block: Array = Array::from([0u8; 16]); + + for _b_num in 0..batch_size { + // Initialize cipher + let cipher = Aes128::new(¤t_key); + + xor_arrays(in_block, tweak, &mut out_block); + // Encrypt block in-place + cipher.encrypt_block(&mut out_block); + xor_array_(&mut out_block, tweak); + + if out_block.eq(search_block) { + return Some(current_key); + } + + let _ = add_one_to_block_(&mut current_key); + } + + return None; +} + +pub fn do_work( + pool: &ThreadPool, + batch_size: u64, + start_key: &[u8; 16], + tweak_key: &[u8; 16], + data_block: &[u8; 16], + search_block: &[u8; 16], +) -> Option> { + + let (tx, rx) = mpsc::channel(); + + let th_num = pool.max_count(); + + let mut a_start_key: Array = Array::from(start_key.clone()); + let a_tweak_key: Array = Array::from(tweak_key.clone()); + let a_data_block: Array = Array::from(data_block.clone()); + let a_search_block: Array = Array::from(search_block.clone()); + + let tweak = gen_tweak_zero_block(&a_tweak_key); + + + for _ in 0..th_num { + let th_start_key = a_start_key.clone(); + let tx = tx.clone(); + pool.execute(move || { + let result = encrypt_and_check( + &th_start_key, + &tweak, + batch_size, + &a_data_block, + &a_search_block, + ); + tx.send(result).unwrap(); + }); + + add_u64_to_arr_u8_(&mut a_start_key, batch_size); + } + + drop(tx); // Close the sending end + + // Collect all results + let results = rx.iter() + .find(|x| x.is_some()) + .unwrap_or(None); + + return results; +} diff --git a/nyash_client_cpu/src/client.rs b/nyash_client_cpu/src/client.rs new file mode 100644 index 0000000..59651fc --- /dev/null +++ b/nyash_client_cpu/src/client.rs @@ -0,0 +1,281 @@ +use std::time::Duration; + +use tokio; +use tonic; +use tonic::transport::Channel; +//use tonic::{Request, Response, Status}; +pub mod nyash_proto { + tonic::include_proto!("nyash_proto"); // The string specified here must match the proto package name +} + +use nyash_proto::nyash_luks_client::NyashLuksClient; +use nyash_proto::{ + CommitReply, KeyData, ProgressReply, ProgressRequest, WorkCommit, WorkReply, WorkRequest, + work_commit, work_reply, +}; + +use std::sync::Arc; +use threadpool::ThreadPool; +use tokio::sync::RwLock as AsyncRwLock; +mod aes_cpu; +pub mod num_utils; +mod search_params; +//mod test_cl; + +const S_ADDR: &str = "http://93.113.25.180:37939"; + + +async fn shutdown_signal() { + let ctrl_c = async { + tokio::signal::ctrl_c() + .await + .expect("Failed to install Ctrl+C handler"); + }; + + #[cfg(unix)] + let terminate = async { + tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) + .expect("Failed to install SIGTERM handler") + .recv() + .await; + }; + + #[cfg(not(unix))] + let terminate = std::future::pending::<()>(); + + tokio::select! { + _ = ctrl_c => println!("Received Ctrl+C, initiating shutdown"), + _ = terminate => println!("Received SIGTERM, initiating shutdown"), + } +} + +// fn key_dat_from_exec_dat(ex_dat: &ExecData) -> KeyData { +// let t_k = num_utils::u128_to_u64arr(num_utils::u32arr_to_u128(num_utils::vec_to_u32_4arr( +// &ex_dat.tweak_key, +// 0, +// ))); +// let e_k = num_utils::u128_to_u64arr(ex_dat.get_found_key()); + +// KeyData { +// start_key0: e_k[0], +// start_key1: e_k[1], +// tweak_key0: t_k[0], +// tweak_key1: t_k[1], +// } +// } + +async fn get_progress(chanel: Channel) -> Result { + let mut client = NyashLuksClient::new(chanel); + + let request = tonic::Request::new(ProgressRequest {}); + let response = client.request_progress(request).await?; + return Ok(response.into_inner()); +} + +async fn get_work(chanel: Channel, work_size: u64) -> Result { + let mut client = NyashLuksClient::new(chanel); + + println!("Requesting work {} keys...", work_size); + let request = tonic::Request::new(WorkRequest { + pref_work_size: work_size, + }); + let response = client.request_work(request).await?; + return Ok(response.into_inner()); +} + +async fn commit_work( + chanel: Channel, + commit_data: WorkCommit, +) -> Result { + let mut client = NyashLuksClient::new(chanel); + + let request = tonic::Request::new(commit_data); + let response = client.commit_work(request).await?; + return Ok(response.into_inner()); +} + +fn benchmark() -> (u64, usize) { + let total_work: u64 = 1280000000; + let thread_num_list: [usize; 9] = [4, 6, 8, 10, 16, 20, 32, 64, 128]; + let mut work_time = [0f64; 9]; + + let mut preffered_th_num: usize = thread_num_list[0]; + let mut preffered_batch_size: u64 = 0; + + let start_key = [1u8; 16]; + let tweak_key = [2u8; 16]; + let data_block = [3u8; 16]; + let search_block = [4u8; 16]; + + for i in 0..9 { + let test_th_num = thread_num_list[i]; + let pool = ThreadPool::new(test_th_num); + let batch_size: u64 = total_work / test_th_num as u64; + + println!("Benchmarking thread num: {}", test_th_num); + for _j in 0..3 { + println!("Run number {}", _j); + let start_time = std::time::Instant::now(); + let res = aes_cpu::do_work( + &pool, + batch_size, + &start_key, + &tweak_key, + &data_block, + &search_block, + ); + if res.is_some() { + println!("Key found!") + } + let exec_duration = start_time.elapsed().as_secs_f64(); + work_time[i] += exec_duration; + } + work_time[i] = work_time[i] / 3.0; + println!("Average time {}", work_time[i]); + if i > 0 { + //giving 2% error for speed mesure + if (work_time[i] * 1.02) > work_time[i - 1] { + break; + } + } + preffered_th_num = test_th_num; + // calculate batch size so it correspond to 30 sec job + preffered_batch_size = (batch_size as f64 * (10.0 / work_time[i])) as u64; + println!( + "batch_size {}, work_time {}, preffered_batch_size {}, preffered_th_num {}", + batch_size, work_time[i], preffered_batch_size, preffered_th_num + ); + } + + return (preffered_batch_size, preffered_th_num); +} + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<(), Box> { + println!("Performing banchmark to determine optimal parameters..."); + let (pref_batch_size, th_num) = benchmark(); + println!("batch_size {}, th_num {}", pref_batch_size, th_num); + + let encrypted_data = search_params::get_encrypted_data(); + let unencrypt_data = [0u8; 16]; + let th_pool = ThreadPool::new(th_num); + + // Don't keep connection alive when idle + let nya_channel: tonic::transport::Channel = tonic::transport::Endpoint::from_static(S_ADDR) + .keep_alive_while_idle(false) + .keep_alive_timeout(Duration::from_secs(10)) + .connect_timeout(Duration::from_secs(10)) + .connect() + .await + .expect("Error connecting to server!"); + + let key_found = match get_progress(nya_channel.clone()).await { + Err(_) => { + println!("Error getting progress!"); + false + } + Ok(p_r) => { + println!("Current progress {:.8}%", p_r.progress * 100.0); + p_r.key_found + } + }; + + let mut giga_keys_per_second: f64 = 0f64; + let req_work_size: u64 = pref_batch_size * th_num as u64; + + let shared_key_found = Arc::new(AsyncRwLock::new(key_found)); + // handling program termination + let sh_k_f_clone = shared_key_found.clone(); + tokio::spawn(async move { + shutdown_signal().await; + //signaling that we should stop + let mut guard = sh_k_f_clone.write().await; + *guard = true; + }); + + while *shared_key_found.read().await == false { + let mut work = get_work(nya_channel.clone(), req_work_size).await; + while work.is_err() { + println!("Error getting work, waiting 15 seconds and trying again..."); + tokio::time::sleep(Duration::from_secs(15)).await; + work = get_work(nya_channel.clone(), req_work_size).await; + } + let work = work.expect("Error getting work!"); + + let work_data = match work.result.expect("Error! Expected WorkResult!") { + work_reply::Result::NoWork(_) => { + println!("No work right now, try again later..."); + continue; + } + work_reply::Result::Error(ex) => { + println!("Erro getting work: {}", ex); + continue; + } + work_reply::Result::WorkData(wd) => wd, + }; + println!("Got work, {} keys...", work_data.work_size); + let start_key = num_utils::u64arr_to_u8arr([work_data.start_key0, work_data.start_key1]); + let tweak_key = num_utils::u64arr_to_u8arr([work_data.tweak_key0, work_data.tweak_key1]); + + let mut batch_size = work_data.work_size / th_num as u64; + if (work_data.work_size % th_num as u64) != 0 { + batch_size += 1; + } + println!("Setting batch size to {}", batch_size); + + println!("Crunching numbers..."); + + let start_time = std::time::Instant::now(); + let work_res = aes_cpu::do_work( + &th_pool, + batch_size, + &start_key, + &tweak_key, + &unencrypt_data, + &encrypted_data, + ); + let exec_duration = start_time.elapsed().as_secs_f64(); + + let g_k_p_s = (work_data.work_size as f64 / exec_duration) / 1000000000.0; + if giga_keys_per_second != 0f64 { + giga_keys_per_second = giga_keys_per_second * 0.9 + g_k_p_s * 0.1; + } else { + giga_keys_per_second = g_k_p_s; + } + println!("Average speed: {:.3}GigaKeys/Sec", giga_keys_per_second); + + let work_c = match work_res { + Some(found_key) => { + println!("We found the key! {:?} {:?}", found_key, tweak_key); + + //signaling that key found + let mut guard = shared_key_found.write().await; + *guard = true; + + let found_key_u64 = num_utils::u8arr_to_u64arr(found_key.into()); + WorkCommit { + work_id: work_data.work_id, + result: Some(work_commit::Result::FoundKey(KeyData { + tweak_key0: work_data.tweak_key0, + tweak_key1: work_data.tweak_key1, + start_key0: found_key_u64[0], + start_key1: found_key_u64[0], + })), + } + } + None => WorkCommit { + work_id: work_data.work_id, + result: Some(work_commit::Result::NoKey(true)), + }, + }; + let resp = commit_work(nya_channel.clone(), work_c).await; + match resp { + Ok(c_r) => println!("Work commited. Progress: {:.8}%", c_r.progress * 100.0), + Err(_) => println!("Error commiting work..."), + }; + } + + println!("Exiting!"); + + Ok(()) +} diff --git a/nyash_client_cpu/src/num_utils.rs b/nyash_client_cpu/src/num_utils.rs new file mode 100644 index 0000000..2a7152c --- /dev/null +++ b/nyash_client_cpu/src/num_utils.rs @@ -0,0 +1,356 @@ +// union U64orU32 { +// l: u64, +// i: [u32; 2], +// } + +pub fn vec_to_u32_4arr(in_v: &Vec, start_idx: usize) -> [u32; 4] { + let mut u32_arr_k = [0u32; 4]; + for i in 0..4 { + u32_arr_k[0] = in_v[start_idx + i]; + } + return u32_arr_k; +} + +pub fn u128_to_u64arr(a: u128) -> [u64; 2] { + let mut res = [0u64; 2]; + let a_bytes = a.to_le_bytes(); + let chunks = a_bytes.as_chunks::<8>().0; + for i in 0..2 { + res[i] = u64::from_le_bytes(chunks[i]); + } + return res; +} + +pub fn u64arr_to_u128(a: [u64; 2]) -> u128 { + let mut bytes_data: [u8; 16] = [0u8; 16]; + bytes_data[0..8].copy_from_slice(a[0].to_le_bytes().as_slice()); + bytes_data[8..].copy_from_slice(a[1].to_le_bytes().as_slice()); + + return u128::from_le_bytes(bytes_data); +} + +pub fn u64arr_to_u8arr(a: [u64; 2]) -> [u8; 16] { + let mut bytes_data: [u8; 16] = [0u8; 16]; + bytes_data[0..8].copy_from_slice(a[0].to_le_bytes().as_slice()); + bytes_data[8..].copy_from_slice(a[1].to_le_bytes().as_slice()); + + return bytes_data; +} + +pub fn u8arr_to_u64arr(a_bytes: [u8; 16]) -> [u64; 2] { + let mut res = [0u64; 2]; + + let chunks = a_bytes.as_chunks::<8>().0; + for i in 0..2 { + res[i] = u64::from_le_bytes(chunks[i]); + } + return res; +} + +pub fn u128_to_u32arr(a: u128) -> [u32; 4] { + let mut res = [0u32; 4]; + let a_bytes = a.to_le_bytes(); + let chunks = a_bytes.as_chunks::<4>().0; + for i in 0..4 { + res[i] = u32::from_le_bytes(chunks[i]); + } + return res; +} + +pub fn u32arr_to_u128(a: [u32; 4]) -> u128 { + let mut bytes_data: [u8; 16] = [0u8; 16]; + bytes_data[0..4].copy_from_slice(a[0].to_le_bytes().as_slice()); + bytes_data[4..8].copy_from_slice(a[1].to_le_bytes().as_slice()); + bytes_data[8..12].copy_from_slice(a[2].to_le_bytes().as_slice()); + bytes_data[12..16].copy_from_slice(a[3].to_le_bytes().as_slice()); + + return u128::from_le_bytes(bytes_data); +} + + + +// fn add_u32_to_u256(a: &[u32; 8], b: u32) -> ([u32; 8], bool) { +// let mut res: [u32; 8] = [0; 8]; +// let mut carry = false; +// (res[0], carry) = a[0].carrying_add(b, carry); + +// for idx in 1..8 { +// (res[idx], carry) = a[idx].carrying_add(0, carry); +// } + +// return (res, carry); +// } + +// fn add_u32_to_u256_(a: &mut [u32; 8], b: u32) -> bool { +// let mut carry = false; +// (a[0], carry) = a[0].carrying_add(b, carry); + +// for idx in 1..8 { +// (a[idx], carry) = a[idx].carrying_add(0, carry); +// } + +// return carry; +// } + +// fn bytes_from_chars(chars_chunk: &[char]) -> [u8; 4] { +// let mut res: [u8; 4] = [0; 4]; +// let mut idx: usize = 0; +// chars_chunk.chunks_exact(2).for_each(|b_c| { +// if idx < 4 { +// match u8::from_str_radix(&b_c.iter().collect::(), 16) { +// Ok(n) => res[idx] = n, +// Err(_) => (), +// } +// idx += 1; +// } +// }); +// return res; +// } + +// fn bignum_from_hex(hex: &str) -> [u32; 8] { +// let mut res: [u32; 8] = [0; 8]; +// let mut idx: usize = 0; +// let chars_hex = hex.chars().collect::>(); +// chars_hex +// .chunks_exact(8) +// .rev() +// .map(|chunk| bytes_from_chars(chunk)) +// .for_each(|b_arr| { +// if idx < 8 { +// res[idx] = u32::from_be_bytes(b_arr); +// idx += 1; +// } +// }); +// return res; +// } + +// fn hex_fmt_byte(n: u32) -> String { +// let res: String = n +// .to_be_bytes() +// .iter() +// .map(|b| format!("{:02x}", b)) +// .collect(); +// return res; +// } + +// fn bignum_to_hex(a: &[u32; 8]) -> String { +// let res: String = a +// .iter() +// .rev() +// .map(|n| hex_fmt_byte(*n)) +// .collect::>() +// .join(""); +// return res; +// } + +// #[cfg(test)] +// mod num_utils_tests { +// use std::io::Read; + +// use super::*; + +// #[test] +// fn test_add() { +// use std::io::{BufRead, BufReader}; +// use std::process::{Command, Stdio}; + +// let test_gen_cmd = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/tests/gen_test_data.py"; +// let mut child = Command::new(test_gen_cmd) +// .stdout(Stdio::piped()) +// .spawn() +// .unwrap(); + +// let gen_stdout = child +// .stdout +// .take() +// .ok_or("Failed to capture stdout") +// .unwrap(); +// let gen_reader = BufReader::new(gen_stdout); + +// for r_line in gen_reader.lines() { +// let test_line: String = r_line.unwrap(); // Handle any I/O errors +// let test_data_line = test_line.split(' ').collect::>(); +// let num_to_add = u32::from_str_radix(test_data_line[0], 10).unwrap(); +// let t0 = bignum_from_hex(test_data_line[1]); + +// let t1_test = add_u32_to_u256(&t0, 1).0; +// let t2_test = add_u32_to_u256(&t0, num_to_add).0; + +// let res_actual = format!( +// "{} {} {} {}", +// num_to_add, +// bignum_to_hex(&t0), +// bignum_to_hex(&t1_test), +// bignum_to_hex(&t2_test) +// ); +// assert_eq!(test_line, res_actual); +// } + +// let _ = child.wait().unwrap(); +// } + +// #[test] +// fn test_cl_add() { +// extern crate ocl; +// use ocl::{Buffer, Context, Device, Kernel, Platform, Program, Queue, flags}; +// use std::fs::File; +// use std::io::{BufRead, BufReader}; +// use std::process::{Command, Stdio}; + +// let cl_test_path = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/open_cl/test_num_utils.cl"; +// let cl_include_opt = +// "-I /home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/open_cl"; +// let mut cl_src = String::new(); +// // read ocl source +// BufReader::new(File::open(cl_test_path).unwrap()) +// .read_to_string(&mut cl_src) +// .expect("Error reading cl_src!"); + +// const G_WORK_SIZE: usize = 4096; + +// let cl_platform = Platform::default(); +// let cl_device = Device::first(cl_platform).unwrap(); +// let cl_context = Context::builder() +// .platform(cl_platform) +// .devices(cl_device.clone()) +// .build() +// .unwrap(); +// let cl_program = Program::builder() +// .devices(cl_device) +// .src(cl_src) +// .cmplr_opt(cl_include_opt) +// .build(&cl_context) +// .unwrap(); +// let cl_queue = Queue::new(&cl_context, cl_device, None).unwrap(); + +// let cl_buffer_num = Buffer::::builder() +// .queue(cl_queue.clone()) +// .flags(flags::MEM_READ_ONLY) +// .len(G_WORK_SIZE) +// .fill_val(0u32) +// .build() +// .unwrap(); + +// let cl_buffer_t0 = Buffer::::builder() +// .queue(cl_queue.clone()) +// .flags(flags::MEM_READ_ONLY) +// .len(G_WORK_SIZE * 8) +// .fill_val(0u32) +// .build() +// .unwrap(); + +// let cl_buffer_t1 = Buffer::::builder() +// .queue(cl_queue.clone()) +// .flags(flags::MEM_WRITE_ONLY) +// .len(G_WORK_SIZE * 8) +// .fill_val(0u32) +// .build() +// .unwrap(); + +// let cl_buffer_t2 = Buffer::::builder() +// .queue(cl_queue.clone()) +// .flags(flags::MEM_WRITE_ONLY) +// .len(G_WORK_SIZE * 8) +// .fill_val(0u32) +// .build() +// .unwrap(); + +// // (3) Create a kernel with arguments matching those in the source above: +// let kernel = Kernel::builder() +// .program(&cl_program) +// .name("test_add") +// .queue(cl_queue.clone()) +// .global_work_size(G_WORK_SIZE) +// .arg(&cl_buffer_num) +// .arg(&cl_buffer_t0) +// .arg(&cl_buffer_t1) +// .arg(&cl_buffer_t2) +// .build() +// .unwrap(); + +// let test_gen_cmd = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/tests/gen_test_data.py"; +// let mut child = Command::new(test_gen_cmd) +// .stdout(Stdio::piped()) +// .spawn() +// .unwrap(); + +// let gen_stdout = child +// .stdout +// .take() +// .ok_or("Failed to capture stdout") +// .unwrap(); +// let gen_reader = BufReader::new(gen_stdout); + +// let mut buffer_num: Vec = vec![0u32; G_WORK_SIZE]; +// let mut buffer_t0: Vec = vec![0u32; G_WORK_SIZE * 8]; +// let mut exp_buffer_t1: Vec = vec![0u32; G_WORK_SIZE * 8]; +// let mut exp_buffer_t2: Vec = vec![0u32; G_WORK_SIZE * 8]; + +// let mut act_buffer_t1: Vec = vec![0u32; G_WORK_SIZE * 8]; +// let mut act_buffer_t2: Vec = vec![0u32; G_WORK_SIZE * 8]; + +// let mut w_id: usize = 0; + +// for r_line in gen_reader.lines() { +// let test_line: String = r_line.unwrap(); // Handle any I/O errors +// let test_data_line = test_line.split(' ').collect::>(); +// let num_to_add = u32::from_str_radix(test_data_line[0], 10).unwrap(); +// buffer_num[w_id] = num_to_add; +// let slise_id = w_id * 8; +// buffer_t0[slise_id..slise_id + 8].copy_from_slice(&bignum_from_hex(test_data_line[1])); +// exp_buffer_t1[slise_id..slise_id + 8] +// .copy_from_slice(&bignum_from_hex(test_data_line[2])); +// exp_buffer_t2[slise_id..slise_id + 8] +// .copy_from_slice(&bignum_from_hex(test_data_line[3])); + +// w_id += 1; +// if w_id >= G_WORK_SIZE { +// w_id = 0; // reset counter +// cl_buffer_num +// .cmd() +// .queue(&cl_queue) +// .offset(0) +// .write(&buffer_num) +// .enq() +// .unwrap(); +// cl_buffer_t0 +// .cmd() +// .queue(&cl_queue) +// .offset(0) +// .write(&buffer_t0) +// .enq() +// .unwrap(); + +// // (4) Run the kernel +// unsafe { +// kernel +// .cmd() +// .queue(&cl_queue) +// .global_work_size(G_WORK_SIZE) +// .enq() +// .unwrap(); +// } + +// cl_buffer_t1 +// .cmd() +// .queue(&cl_queue) +// .offset(0) +// .read(&mut act_buffer_t1) +// .enq() +// .unwrap(); +// cl_buffer_t2 +// .cmd() +// .queue(&cl_queue) +// .offset(0) +// .read(&mut act_buffer_t2) +// .enq() +// .unwrap(); + +// assert_eq!(exp_buffer_t1, act_buffer_t1); +// assert_eq!(exp_buffer_t2, act_buffer_t2); +// } +// } + +// let _ = child.wait().unwrap(); +// } +// } diff --git a/nyash_client_cpu/src/old_main.rs b/nyash_client_cpu/src/old_main.rs new file mode 100644 index 0000000..cb5c2c7 --- /dev/null +++ b/nyash_client_cpu/src/old_main.rs @@ -0,0 +1,399 @@ +extern crate ocl; +use ocl::{ + Buffer, Context, Device, DeviceType, Kernel, Platform, Program, Queue, SpatialDims, flags, +}; +use serde::de::value::Error; +use std::{ + io, + str::{self, FromStr}, +}; + +use crate::client_config::{AppConfig, DevConf}; + +mod client_config; +mod num_utils; + + +fn dev_type_from_str(s: &str) -> Result { + match s { + "CPU" => Ok(flags::DeviceType::CPU), + "GPU" => Ok(flags::DeviceType::GPU), + "ALL" => Ok(flags::DeviceType::ALL), + "CUSTOM" => Ok(flags::DeviceType::CUSTOM), + "ACCELERATOR" => Ok(flags::DeviceType::ACCELERATOR), + "DEFAULT" => Ok(flags::DeviceType::DEFAULT), + _ => Err(()), + } +} + +fn str_or_empty(r: ocl::error::Result) -> String { + match r { + Ok(s) => s, + Err(_) => "".to_string(), + } +} + +fn print_devices(dev_list: &Vec<(Device, Platform)>) { + let mut i = 0; + for (dev, plt) in dev_list.iter() { + let dev_name = str_or_empty(dev.name()); + let plt_name = str_or_empty(plt.name()); + println!("({i}) device: \"{dev_name}\" ----- platorm: \"{plt_name}\""); + i += 1; + } +} + +fn choose_devices(devices_num: usize) -> Result, String> { + println!("Please input desired devices to use as a white space separated list of numbers."); + let mut result: Vec = Vec::new(); + + let mut s_devs_nums = String::new(); + + io::stdin() + .read_line(&mut s_devs_nums) + .expect("Failed to read line"); + + for s_dev_num in s_devs_nums.split(' ') { + let dev_num: usize = match s_dev_num.trim().parse() { + Ok(num) => num, + Err(_) => return Err("You must input a number from device list.".to_string()), + }; + if dev_num >= devices_num { + return Err("You must input a number from device list.".to_string()); + }; + result.push(dev_num); + } + return Ok(result); +} + +fn list_devices(dev_type: DeviceType) -> Vec<(Device, Platform)> { + let platforms = Platform::list(); + let mut devices: Vec<(Device, Platform)> = Vec::new(); + for plt in platforms.iter() { + //let plat_name = str_or_empty(plt.name()); + let list_res = Device::list(plt, Some(dev_type)); + match list_res { + Ok(dev_l) => devices.extend(dev_l.iter().map(|dev| (*dev, plt.clone()))), + Err(_) => {} + } + } + return devices; +} + +// fn init_devices( +// devices: Vec<(Device, Platform, DevConfig)>, +// kern_name: String, +// prog_src: String, +// inc_dirs: Vec, +// ) -> Vec { +// let mut contexts: Vec = Vec::with_capacity(devices.len()); +// for (dev, plt, dev_cfg) in devices { +// let ctx = match Context::builder() +// .platform(plt) +// .devices(dev.clone()) +// .build() +// { +// Ok(c) => c, +// Err(_) => continue, +// }; + +// let prg = match Program::builder().devices(dev).src(&prog_src).build(&ctx) { +// Ok(p) => p, +// Err(_) => continue, +// }; + +// let queue = match Queue::new(&ctx, dev, None) { +// Ok(q) => q, +// Err(_) => continue, +// }; + +// // Create Buffers: +// let start_key_b = match Buffer::::builder() +// .queue(queue.clone()) +// .flags(flags::MEM_READ_ONLY) +// .len(8) +// .fill_val(0u32) +// .build() +// { +// Ok(buf) => buf, +// Err(_) => continue, +// }; + +// let u_data_b = match Buffer::::builder() +// .queue(queue.clone()) +// .flags(flags::MEM_READ_ONLY) +// .len(4) +// .fill_val(0u32) +// .build() +// { +// Ok(buf) => buf, +// Err(_) => continue, +// }; + +// let enc_data_b = match Buffer::::builder() +// .queue(queue.clone()) +// .flags(flags::MEM_READ_ONLY) +// .len(4) +// .fill_val(0u32) +// .build() +// { +// Ok(buf) => buf, +// Err(_) => continue, +// }; + +// let key_found_b = match Buffer::::builder() +// .queue(queue.clone()) +// .flags(flags::MEM_WRITE_ONLY) +// .len(1) +// .fill_val(0u32) +// .build() +// { +// Ok(buf) => buf, +// Err(_) => continue, +// }; + +// // (3) Create a kernel with arguments matching those in the source above: +// let kernel = match Kernel::builder() +// .program(&prg) +// .name(&kern_name) +// .queue(queue.clone()) +// .global_work_size(dev_cfg.global_work_size) +// .arg(&start_key_b) +// .arg(&u_data_b) +// .arg(&enc_data_b) +// .arg(&key_found_b) +// .build() +// { +// Ok(kern) => kern, +// Err(_) => continue, +// }; + +// contexts.push(ExecContext { +// cfg: dev_cfg, +// ctx: ctx, +// kernel: kernel, +// prog: prg, +// queue: queue, +// buffers: CtxBuffers { +// start_key: start_key_b, +// u_data: u_data_b, +// enc_data: enc_data_b, +// key_found: key_found_b, +// }, +// }); +// } +// return contexts; +// } + +fn dev_sel_dialog(all_devices: &Vec<(Device, Platform)>) -> Vec { + let devs_nums = loop { + print_devices(&all_devices); + match choose_devices(all_devices.len()) { + Ok(value) => break value, + Err(exc) => { + println!("Error! {exc}\n") + } + } + }; + return devs_nums; +} + +fn get_devices_conf(file_name: &str) -> Result<(Vec<(Device, Platform)>, AppConfig), String> { + let dev_type = dev_type_from_str("GPU").expect("Unexpected device type!"); + + // Get devices to be used for key search + let all_devices: Vec<(Device, Platform)> = list_devices(dev_type); + if all_devices.len() == 0 { + return Err("Cannot find any usable devices.".to_string()); + }; + + let app_conf = match client_config::load_config(file_name) { + Ok(readed_config) => { + let dev_found = all_devices + .iter() + .filter(|dp| readed_config.device_exist(&dp.0)) + .count(); + if dev_found < readed_config.devices.len() { + println!("Devices from config not found in the system!"); + let devs_nums = dev_sel_dialog(&all_devices); + let res = AppConfig::from_dev_list(&all_devices, devs_nums); + client_config::save_config(file_name, &res); + res + } else { + readed_config + } + } + Err(_) => { + println!("Cannot find config file {}", file_name); + let devs_nums = dev_sel_dialog(&all_devices); + AppConfig::from_dev_list(&all_devices, devs_nums) + } + }; + + let selected_devs = all_devices + .iter() + .filter(|dp| app_conf.device_exist(&dp.0)) + .cloned() + .collect(); + + return Ok((selected_devs, app_conf)); +} + +struct CtxBuffers { + batch_size: u32, + tweak_i: u64, + tweak_j: u32, + start_key: Buffer, + uenc_data: Buffer, + target_data: Buffer, + key_found: Buffer, +} + +struct ExecData { + start_key: Vec, + uenc_data: Vec, + target_data: Vec, + key_found: Vec, + batch_size: u32, + work_size: usize, +} +struct ExecContext { + ctx: Context, + kernel: Kernel, + prog: Program, + queue: Queue, + buffers: CtxBuffers, + exec_data: ExecData, +} + +fn init_program( + cl_device: Device, + cl_platform: Platform, + cl_src: &str, + cl_cmplr_opt: &str, +) -> Result<(Context, Program, Queue), ocl::Error> { + let cl_context = Context::builder() + .platform(cl_platform) + .devices(cl_device.clone()) + .build()?; + + let cl_program = Program::builder() + .devices(cl_device) + .src(cl_src) + .cmplr_opt(cl_cmplr_opt) + .build(&cl_context) + .unwrap(); + + let cl_queue: Queue = Queue::new(&cl_context, cl_device, None)?; + + return Ok((cl_context, cl_program, cl_queue)); +} + +fn init_buffers(cl_queue: Queue) -> Result { + let cl_buffer_start_key = Buffer::::builder() + .queue(cl_queue.clone()) + .flags(flags::MEM_READ_ONLY) + .len(8) + .fill_val(0u32) + .build()?; + + let cl_buffer_uenc_data = Buffer::::builder() + .queue(cl_queue.clone()) + .flags(flags::MEM_READ_ONLY) + .len(4) + .fill_val(0u32) + .build()?; + + let cl_buffer_target_data = Buffer::::builder() + .queue(cl_queue.clone()) + .flags(flags::MEM_READ_ONLY) + .len(4) + .fill_val(0u32) + .build()?; + + let cl_buffer_key_found = Buffer::::builder() + .queue(cl_queue.clone()) + .flags(flags::MEM_WRITE_ONLY) + .len(9) + .fill_val(0u32) + .build()?; + + Ok(CtxBuffers { + batch_size: 0, + tweak_i: 0, + tweak_j: 0, + start_key: cl_buffer_start_key, + uenc_data: cl_buffer_uenc_data, + target_data: cl_buffer_target_data, + key_found: cl_buffer_key_found, + }) +} + +fn init_kernel( + work_size: usize, + cl_program: Program, + cl_queue: Queue, + buffs: &CtxBuffers, +) -> Result { + Kernel::builder() + .program(&cl_program) + .name("search_key") + .queue(cl_queue.clone()) + .global_work_size(work_size) + .arg(&buffs.batch_size) + .arg(&buffs.tweak_i) + .arg(&buffs.tweak_j) + .arg(&buffs.start_key) + .arg(&buffs.uenc_data) + .arg(&buffs.target_data) + .arg(&buffs.key_found) + .build() +} + +fn do_work(ex_ctx: &mut ExecContext) -> Result { + ex_ctx.buffers.batch_size = ex_ctx.exec_data.batch_size; + ex_ctx + .buffers + .start_key + .cmd() + .queue(&ex_ctx.queue) + .offset(0) + .write(&ex_ctx.exec_data.start_key) + .enq()?; + + // (4) Run the kernel + unsafe { + ex_ctx + .kernel + .cmd() + .queue(&ex_ctx.queue) + .global_work_size(ex_ctx.exec_data.work_size) + .enq()?; + } + + ex_ctx + .buffers + .key_found + .cmd() + .queue(&ex_ctx.queue) + .offset(0) + .read(&mut ex_ctx.exec_data.key_found) + .enq()?; + + if ex_ctx.exec_data.key_found[0] == 0{Ok(false)} + else {Ok(true)} +} + +fn main() { + println!("Hello, world nya!"); + //use ocl::{Buffer, Context, Device, Kernel, Platform, Program, Queue, flags}; + let devices = get_devices_conf("test.json"); + println!("{:?}", devices); + + // let devices: Vec<_> = platforms.iter().flat_map(|p| Device::list(p, Some(dev_type)).iter()).collect(); + // let device = Device::first(platform)?; + // let context = Context::builder() + // .platform(platform) + // .devices(device.clone()) + // .build()?; +} diff --git a/nyash_client_cpu/src/search_params.rs b/nyash_client_cpu/src/search_params.rs new file mode 100644 index 0000000..6a1ffa4 --- /dev/null +++ b/nyash_client_cpu/src/search_params.rs @@ -0,0 +1,8 @@ +pub fn get_encrypted_data() -> [u8; 16] { + + let enc_data: [u8; 16] = [ + 10, 51, 110, 227, 194, 181, 104, 65, 151, 47, 69, 37, 66, 223, 71, 137, + ]; + + return enc_data; +} diff --git a/nyash_client_cpu/src/test_cl.rs b/nyash_client_cpu/src/test_cl.rs new file mode 100644 index 0000000..df8162c --- /dev/null +++ b/nyash_client_cpu/src/test_cl.rs @@ -0,0 +1,79 @@ + +#[cfg(test)] +mod test_cl { + #[test] + fn test_encryption() { + use ocl::{Device, Platform}; + use crate::ocl_utils; + use crate::num_utils; + + + const SRC_PATH: &str = "src/open_cl/nyash_aes_xts256_plain.cl"; + const OCL_COMP_OPT: &str = "-I src/open_cl"; + const ENCRYPTED_DATA: [u8; 16] = [ + 198, 255, 55, 185, 15, 226, 223, 174, 119, 8, 36, 239, 242, 89, 126, 230 + ]; + const KEY_DATA: [u8; 32] = [ + 206, 193, 83, 54, 46, 234, 185, 41, 146, 244, 130, 6, 212, 68, 106, 162, 165, 97, 188, + 218, 39, 111, 141, 236, 67, 159, 157, 157, 166, 79, 89, 134 + ]; + + // let key_bytes_reversed: Vec = KEY_DATA.iter().rev().map(|e| *e).collect(); + // let data_bytes_reversed: Vec = ENCRYPTED_DATA.iter().rev().map(|e| *e).collect(); + + let mut tweak_key_b: [u8;16] = [0u8;16]; + let mut data_key_b: [u8;16] = [0u8;16]; + + data_key_b.copy_from_slice(&KEY_DATA[0..16]); + tweak_key_b.copy_from_slice(&KEY_DATA[16..32]); + + // getting keys + let data_key = u128::from_le_bytes(data_key_b); + let tweak_key = u128::from_le_bytes(tweak_key_b); + let data_key = num_utils::u128_to_u32arr(data_key); + let tweak_key = num_utils::u128_to_u32arr(tweak_key); + + + // converting bytes raw data to u32 arr + let mut encrypted_data: [u32; 4] = [0u32; 4]; + let (enc_dat_bytes_chunks, _) = ENCRYPTED_DATA.as_chunks::<4>(); + for i in 0..4 { + encrypted_data[i] = u32::from_le_bytes(enc_dat_bytes_chunks[i]); + } + + // init devices + let platform = Platform::first().expect("Error getting platform!"); + let device = Device::first(platform).expect("Error getting device!"); + + println!("Platform: {:?}, Device: {:?}", platform.name().unwrap(), device.name().unwrap()); + + // reading ocl program sources + let prog_src = std::fs::read_to_string(SRC_PATH).expect("Error reading program sources!"); + + let mut nyan_context = + ocl_utils::ExecContext::new(device, platform, prog_src.as_str(), OCL_COMP_OPT, 256) + .expect("Error creating execution nyan context!"); + + + //setting data + let mut nyan_exec_dat = ocl_utils::ExecData { + start_key: data_key.to_vec(), + tweak_key: tweak_key.to_vec(), + uenc_data: vec![0u32;4], + target_data: encrypted_data.to_vec(), + tweak_i: 0, + tweak_j: 0, + key_found: vec![0u32;5], + batch_size: 1000000, + work_size: 256, + }; + + println!("Set target data"); + ocl_utils::set_target_data(&mut nyan_context, &mut nyan_exec_dat).expect("Error set target data!"); + + let found_flag = ocl_utils::do_work(&mut nyan_context, &mut nyan_exec_dat).expect("Error do work!"); + println!("Found?: {}", found_flag); + println!("Key found: {:?}", nyan_exec_dat.key_found); + assert_eq!(true, found_flag); + } +} diff --git a/nyash_client_cpu/src/test_data/__pycache__/utils.cpython-314.pyc b/nyash_client_cpu/src/test_data/__pycache__/utils.cpython-314.pyc new file mode 100644 index 0000000..687fe78 Binary files /dev/null and b/nyash_client_cpu/src/test_data/__pycache__/utils.cpython-314.pyc differ diff --git a/nyash_client_cpu/src/test_data/create_test.sh b/nyash_client_cpu/src/test_data/create_test.sh new file mode 100644 index 0000000..c68c5bc --- /dev/null +++ b/nyash_client_cpu/src/test_data/create_test.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +truncate -s 255M test_btrfs.img +dd if=/dev/urandom of=master.key bs=32 count=1 + +cryptsetup luksFormat --type=luks2 --sector-size 512 --pbkdf=pbkdf2 --pbkdf-force-iterations=1000 --hash=sha256 --key-size=256 --cipher=aes-xts-plain64 --master-key-file ./test_master.key ./test.img + +cryptsetup luksFormat --type=luks2 --pbkdf=pbkdf2 --pbkdf-force-iterations=1000 --hash=sha256 --key-size=256 --cipher=aes-xts-plain64 ./luks-container.img + +sudo cryptsetup luksOpen ./test.img luks-container-crypt + +sudo mkfs.btrfs /dev/mapper/luks-container-crypt + +sudo dd if=/dev/mapper/luks-container-crypt of=./test_btrfs_luks_unencrypt.img bs=1M count=255 + +sudo cryptsetup close luks-container-crypt diff --git a/nyash_client_cpu/src/test_data/extract_encrypted_block.py b/nyash_client_cpu/src/test_data/extract_encrypted_block.py new file mode 100644 index 0000000..3063cdf --- /dev/null +++ b/nyash_client_cpu/src/test_data/extract_encrypted_block.py @@ -0,0 +1,42 @@ +from utils import read_metadata + + +# Init logger + +LUKS_FILE_NAME = "vg1-volume_1.img" +KEY_FILE_NAME = "master.key" + + + + +def main(): + + metadat = read_metadata(LUKS_FILE_NAME) + print(f"metadata:\n{metadat}") + + + segments_offset_bytes = int(metadat["segments"]["0"]["offset"]) + superblock_start_bytes = 0x00010000 + superblock_start_sector = superblock_start_bytes//512 + magic_offset = 0x40 + superblock_lenght_bytes = 0x1000 + sector_size = 512 + + with open(LUKS_FILE_NAME, 'rb') as luks_file: + luks_file.seek(segments_offset_bytes) + enc_data = luks_file.read(16) + + + print("ENC DATA:") + print("[" + ",".join([format(a, 'd') for a in enc_data])+"]") + # + # print() + # print("KEY DATA:") + # with open(KEY_FILE_NAME, 'rb') as key_file: + # key_data = key_file.read(32) + # print("[" + ",".join([format(a, 'd') for a in key_data])+"]") + + + +if __name__ == '__main__': + main() diff --git a/nyash_client_cpu/src/test_data/utils.py b/nyash_client_cpu/src/test_data/utils.py new file mode 100644 index 0000000..8fd40fd --- /dev/null +++ b/nyash_client_cpu/src/test_data/utils.py @@ -0,0 +1,25 @@ +import subprocess +import json + +def read_metadata(file_name: str) -> dict: + #cryptsetup luksDump --dump-json-metadata /dev/loop0 + luks_cmd: list[str] = ["cryptsetup", "luksDump", "--dump-json-metadata", file_name] + + result = subprocess.run(luks_cmd, capture_output=True, encoding="UTF-8") + if result.returncode == 0 and result.stdout is not None: + metadata = json.loads(result.stdout) + return metadata + else: + raise Exception(f"Error executing 'cryptsetup' binary! {result.stderr}") + + +def read_encrypted_key(f_name: str, metadata: dict, keyslot: int) -> bytes: + stripes = metadata["keyslots"][str(keyslot)]["af"]["stripes"] + offset = int(metadata["keyslots"][str(keyslot)]["area"]["offset"]) + # size = int(metadata["keyslots"][str(keyslot)]["area"]["size"]) + key_size = metadata["keyslots"][str(keyslot)]["area"]["key_size"] + with open(f_name, 'rb') as luks_file: + luks_file.seek(offset) + data = luks_file.read(key_size*stripes) + return data + diff --git a/nyash_client_cpu/src/test_nums.rs b/nyash_client_cpu/src/test_nums.rs new file mode 100644 index 0000000..9b16fa2 --- /dev/null +++ b/nyash_client_cpu/src/test_nums.rs @@ -0,0 +1,47 @@ + + + +#[cfg(test)] +mod cl_num_utils_tests { + use super::*; + + #[test] + fn test_add() { + use std::io::{BufRead, BufReader}; + use std::process::{Command, Stdio}; + + let test_gen_cmd = "/home/kira/Development/Rust/nyash-aes-xts256-plain64/nyash_client/src/tests/gen_test_data.py"; + let mut child = Command::new(test_gen_cmd) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + + let gen_stdout = child + .stdout + .take() + .ok_or("Failed to capture stdout") + .unwrap(); + let gen_reader = BufReader::new(gen_stdout); + + for r_line in gen_reader.lines() { + let test_line: String = r_line.unwrap(); // Handle any I/O errors + let test_data_line = test_line.split(' ').collect::>(); + let num_to_add = u32::from_str_radix(test_data_line[0], 10).unwrap(); + let t0 = bignum_from_hex(test_data_line[1]); + + let t1_test = add_u32_to_u256(&t0, 1).0; + let t2_test = add_u32_to_u256(&t0, num_to_add).0; + + let res_actual = format!( + "{} {} {} {}", + num_to_add, + bignum_to_hex(&t0), + bignum_to_hex(&t1_test), + bignum_to_hex(&t2_test) + ); + assert_eq!(test_line, res_actual); + } + + let _ = child.wait().unwrap(); + } +} \ No newline at end of file diff --git a/nyash_client_cpu/src/tests/gen_test_data.py b/nyash_client_cpu/src/tests/gen_test_data.py new file mode 100755 index 0000000..b5e5f28 --- /dev/null +++ b/nyash_client_cpu/src/tests/gen_test_data.py @@ -0,0 +1,21 @@ +#!/usr/bin/python +import random + + +def main(iters: int): + for i in range(iters): + rand_u32 = random.randint(1,0xffffffff) + t0 = int.from_bytes(random.randbytes(32)) + t1 = t0 + 1 + t2 = t0 + rand_u32 + print(f"{rand_u32} {t0.to_bytes(32).hex()} {t1.to_bytes(32).hex()} {t2.to_bytes(32).hex()}") + +if __name__ == '__main__': + main(1000000) + + + + + + +