diff --git a/.gitignore b/.gitignore index 97819467..64f4d980 100644 --- a/.gitignore +++ b/.gitignore @@ -10,9 +10,9 @@ workspace.code-workspace .cargo/config.toml # Test Data -vach/test_data/encrypted/target.vach -vach/test_data/signed/target.vach -vach/test_data/simple/target.vach +./vach/test_data/encrypted/target.vach +./vach/test_data/signed/target.vach +./vach/test_data/simple/target.vach # Cargo .cargo \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 186351b6..eecd485f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aead" @@ -69,15 +69,15 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "atty" @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "base64ct" @@ -110,9 +110,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" [[package]] name = "block-buffer" @@ -156,6 +156,12 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cast" version = "0.3.0" @@ -222,21 +228,21 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.11" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.11" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" dependencies = [ "anstyle", - "clap_lex 0.7.2", + "clap_lex 0.7.4", ] [[package]] @@ -250,21 +256,21 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "console" -version = "0.15.8" +version = "0.15.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "unicode-width", - "windows-sys", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", ] [[package]] @@ -275,9 +281,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -291,7 +297,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.11", + "clap 4.5.26", "criterion-plot", "is-terminal", "itertools", @@ -320,9 +326,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -339,9 +345,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" @@ -393,7 +399,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.96", ] [[package]] @@ -448,25 +454,25 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fiat-crypto" @@ -548,6 +554,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "indexmap" version = "1.9.3" @@ -560,15 +572,15 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" dependencies = [ "console", - "instant", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.2.0", + "web-time", ] [[package]] @@ -580,24 +592,15 @@ dependencies = [ "generic-array", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi 0.4.0", "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -611,36 +614,31 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" -version = "0.2.155" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "log" @@ -690,9 +688,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" @@ -720,7 +718,7 @@ checksum = "9ad43c07024ef767f9160710b3a6773976194758c7919b17e63b863db0bdf7fb" dependencies = [ "bytecount", "fnv", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -735,9 +733,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -748,15 +746,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] @@ -775,15 +773,18 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro-error" @@ -811,18 +812,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -879,9 +880,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -891,9 +892,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -902,30 +903,30 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.7.0", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -945,35 +946,35 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.96", ] [[package]] name = "serde_json" -version = "1.0.121" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab380d7d9f22ef3f21ad3e6c1ebe8e4fc7a2000ccba2e4d71fc96f15b2cb609" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", "memchr", @@ -1048,9 +1049,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.72" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -1065,7 +1066,7 @@ checksum = "4c998b0c8b921495196a48aabaf1901ff28be0760136e31604f7967b0792050e" dependencies = [ "papergrid", "tabled_derive", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] @@ -1083,14 +1084,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", + "getrandom", + "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1110,22 +1113,22 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.96", ] [[package]] @@ -1156,15 +1159,21 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "universal-hash" @@ -1251,34 +1260,34 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.96", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1286,28 +1295,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -1331,11 +1350,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1353,6 +1372,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1417,6 +1445,27 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + [[package]] name = "zeroize" version = "1.8.1" diff --git a/README.md b/README.md index 7195c5a8..daaf1048 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Docs | Repo

-`vach`, pronounced like "puck" but with a "v", is an archiving and resource transmission format. It was built to be secure, contained and protected. It was, in fact, designed by the [SCP](https://en.wikipedia.org/wiki/SCP_Foundation) to keep your anomalous assets compact and secure during transmission. `vach` also has in-built support for multiple compression schemes (LZ4, Snappy and Brolti), [data signing](https://github.com/dalek-cryptography/ed25519-dalek), leaf [bitflags](https://docs.rs/vach/latest/vach/archive/struct.Flags.html), [encryption](https://docs.rs/aes-gcm/latest/aes_gcm/) and some degree of archive customization. Check out the `vach` spec at **[spec.txt](https://github.com/zeskeertwee/vach/blob/main/spec/main.txt)**. Any and *all* help will be much appreciated, especially proof reading the docs and code review. +`vach`, pronounced like "duck" but with a "v", is an archiving and resource transmission format. It was built to be secure, contained and protected. It was, in fact, designed by the [SCP](https://en.wikipedia.org/wiki/SCP_Foundation) to keep your anomalous assets compact and secure during transmission. `vach` also has in-built support for multiple compression schemes (LZ4, Snappy and Brolti), [data signing](https://github.com/dalek-cryptography/ed25519-dalek), leaf [bitflags](https://docs.rs/vach/latest/vach/archive/struct.Flags.html), [encryption](https://docs.rs/aes-gcm/latest/aes_gcm/) and some degree of archive customization. Check out the `vach` spec at **[spec.txt](https://github.com/zeskeertwee/vach/blob/main/spec/main.txt)**. Any and *all* help will be much appreciated, especially proof reading the docs and code review. --- @@ -79,9 +79,8 @@ let target = File::open("sounds.vach")?; let mut archive = Archive::new(target)?; let resource: Resource = archive.fetch_mut("ambient")?; -// By default all resources are flagged as NOT authenticated -println!("{}", Sound::new(&resource.data)?); -assert!(!resource.authenticated); +// By default all resources are flagged as NOT verified +assert!(!resource.verified); ``` ##### > Build a signed `.vach` file @@ -147,8 +146,7 @@ let mut archive = Archive::with_config(target, &config)?; // Resources are marked as secure (=true) if the signatures match the data let resource = archive.fetch_mut("ambient")?; -println!("{}", Sound::new(&resource.data)?); -assert!(resource.authenticated); +assert!(resource.verified); ``` ##### > A quick consolidated example diff --git a/vach-cli/src/commands/pack.rs b/vach-cli/src/commands/pack.rs index 3a3acd7a..abf39769 100644 --- a/vach-cli/src/commands/pack.rs +++ b/vach-cli/src/commands/pack.rs @@ -16,9 +16,9 @@ use crate::keys::key_names; pub const VERSION: &str = "0.0.5"; -struct FileWrapper(PathBuf, Option); +struct FileAutoDropper(PathBuf, Option); -impl Read for FileWrapper { +impl Read for FileAutoDropper { fn read(&mut self, buf: &mut [u8]) -> io::Result { // If no file is defined open it let file = match self.1.as_mut() { @@ -28,11 +28,11 @@ impl Read for FileWrapper { self.1.as_mut().unwrap() }, }; - let result = file.read(buf); - // Once the file is done reading, we drop the file handle - // TOo avoid hitting OS limitations + let result = file.read(buf); if let Ok(0) = result { + // Once the file is done reading, we drop the file handle + // To avoid hitting OS limitations self.1.take(); }; @@ -125,7 +125,7 @@ impl CommandTrait for Evaluator { if let Some(val) = args.values_of(key_names::INPUT) { val.map(PathBuf::from) .filter(|f| path_filter(f)) - .for_each(|p| inputs.push(FileWrapper(p, None))); + .for_each(|p| inputs.push(FileAutoDropper(p, None))); }; // Extract directory inputs @@ -136,7 +136,7 @@ impl CommandTrait for Evaluator { .into_iter() .map(|v| v.unwrap().into_path()) .filter(|f| path_filter(f)) - .for_each(|p| inputs.push(FileWrapper(p, None))) + .for_each(|p| inputs.push(FileAutoDropper(p, None))) }); }; @@ -145,7 +145,7 @@ impl CommandTrait for Evaluator { val.flat_map(|dir| walkdir::WalkDir::new(dir).into_iter()) .map(|v| v.unwrap().into_path()) .filter(|f| path_filter(f)) - .for_each(|p| inputs.push(FileWrapper(p, None))); + .for_each(|p| inputs.push(FileAutoDropper(p, None))); } // Read valueless flags diff --git a/vach-cli/src/commands/unpack.rs b/vach-cli/src/commands/unpack.rs index 72d54fb2..a0270dca 100644 --- a/vach-cli/src/commands/unpack.rs +++ b/vach-cli/src/commands/unpack.rs @@ -80,16 +80,13 @@ impl CommandTrait for Evaluator { }, }; - let mut num_threads = args + let num_threads = args .value_of(key_names::JOBS) .map(|v| v.parse::().ok()) .flatten() + .filter(|s| *s > 0) .unwrap_or(num_cpus::get()); - if num_threads == 0 { - num_threads = num_cpus::get() - } - extract_archive(&archive, num_threads, output_path)?; // Delete original archive @@ -118,7 +115,6 @@ fn extract_archive( let pbar = ProgressBar::new(total_size); - // NOTE: More styling is to come pbar.set_style( ProgressStyle::default_bar() .template(super::PROGRESS_BAR_STYLE)? diff --git a/vach/Cargo.toml b/vach/Cargo.toml index c34f5e07..f43a7e4b 100644 --- a/vach/Cargo.toml +++ b/vach/Cargo.toml @@ -15,7 +15,7 @@ repository = "https://github.com/zeskeertwee/vach" categories = ["games", "compression"] keywords = ["archive", "filesystem", "compression", "game", "assets"] documentation = "https://docs.rs/vach" -readme = "README.md" +readme = "../README.md" include = ["Cargo.toml", "Cargo.lock", "src/*"] [dependencies] diff --git a/vach/README.md b/vach/README.md deleted file mode 100644 index dbe5c942..00000000 --- a/vach/README.md +++ /dev/null @@ -1,47 +0,0 @@ -

-GitHub last commit - docs.rs - Crate Version on Crates.io -
- GitHub - GitHub Build and Test actions - GitHub issues -

-

- Docs | Repo -

- -`vach`, pronounced like "puck" but with a "v", is an archiving and resource transmission format. It was built to be secure, contained and protected. It was, in fact, designed by the [SCP](https://en.wikipedia.org/wiki/SCP_Foundation) to keep your anomalous assets compact and secure during transmission. A big benefit of `vach` is the fine grained control it grants it's users, as it allows for per-entry independent configuration. `vach` also has in-built support for multiple compression schemes (LZ4, Snappy and Brolti), [data signing](https://github.com/dalek-cryptography/ed25519-dalek), leaf [bitflags](https://docs.rs/vach/latest/vach/archive/struct.Flags.html), [encryption](https://docs.rs/aes-gcm/latest/aes_gcm/) and some degree of archive customization. Check out the `vach` spec at **[spec.txt](https://github.com/zeskeertwee/vach/blob/main/spec/main.txt)**. Any and *all* help will be much appreciated, especially proof reading the docs and code review. - -## ⛏ Who is this for? - -- You just released some software and don't want your assets pirated or easily read. -- You want a simple convenient way to manage, decompress, decrypt and authenticate assets in distribution. -- You want a pure Rust™️ archive format with no C bindings underneath (bindings **for** C may become available in the future). -- You want your software to be neat, and all your assets to be in one neat secure container. -- You like orbital cannons. - -## 🧷 Simple usage - -```rust -use std::fs::File; -use vach::prelude::{Archive, Resource, Flags}; - -let source = File::open("sounds.vach")?; - -let mut archive = Archive::new(source)?; -let resource: Resource = archive.fetch_mut("footstep.wav")?; - -// By default all resources are flagged as NOT secure -assert!(!resource.authenticated); - -// Use the data -use my_crate::Sound; -println!("{}", Sound::new(resource.data.as_slice())?); - -// Read data directly into an `io::Write` stream -let mut buffer = Vec::new(); -let (flags, content_version, is_secure) = archive.fetch_mut("ftstep", &mut buffer)?; -``` - -> For more information on how to use the crate, read the [documentation](https://docs.rs/vach) or pass by the [repository](https://github.com/zeskeertwee/vach). Maybe also check out the [CLI](https://crates.io/crates/vach-cli), for a more user-friendly use of `vach` diff --git a/vach/src/lib.rs b/vach/src/lib.rs index 272855d4..aae1abf5 100644 --- a/vach/src/lib.rs +++ b/vach/src/lib.rs @@ -61,9 +61,8 @@ let target = File::open("sounds.vach")?; let mut archive = Archive::new(target)?; let resource: Resource = archive.fetch_mut("ambient")?; -// By default all resources are flagged as NOT authenticated -println!("{}", Sound::new(&resource.data)?); -assert!(!resource.authenticated); +// By default all resources are flagged as NOT verified +assert!(!resource.verified); let resource = archive.fetch_mut("ftstep")?; ``` @@ -106,8 +105,7 @@ let archive = Archive::with_config(target, &config)?; // Resources are marked as secure (=true) if the signatures match the data let mut resource = archive.fetch_mut("ambient")?; -println!("{}", Sound::new(&resource.data)?); -assert!(resource.authenticated); +assert!(resource.verified); ``` ##### > Serialize and de-serialize a `Keypair`, `SecretKey` and `PublicKey` diff --git a/vach/src/loader/archive.rs b/vach/src/loader/archive.rs index 7374bf05..d318962a 100644 --- a/vach/src/loader/archive.rs +++ b/vach/src/loader/archive.rs @@ -78,7 +78,7 @@ impl Archive { // buffer_a originally contains the raw data let mut decrypted = None; - let mut is_secure = false; + let mut verified = false; // Signature validation // Validate signature only if a public key is passed with Some(PUBLIC_KEY) @@ -91,7 +91,7 @@ impl Archive { let entry_bytes = entry.to_bytes(true)?; raw.extend_from_slice(&entry_bytes); - is_secure = pk.verify_strict(&raw, &signature).is_ok(); + verified = pk.verify_strict(&raw, &signature).is_ok(); raw.truncate(raw_size); } } @@ -144,15 +144,15 @@ impl Archive { )); }; - Ok((target, is_secure)) + Ok((target, verified)) } #[cfg(not(feature = "compression"))] Err(InternalError::MissingFeatureError("compression")) } else { match decrypted { - Some(decrypted) => Ok((decrypted, is_secure)), - None => Ok((raw, is_secure)), + Some(decrypted) => Ok((decrypted, verified)), + None => Ok((raw, verified)), } } } @@ -251,13 +251,13 @@ where // Prepare contextual variables // Decompress and|or decrypt the data - let (buffer, is_secure) = self.process(&entry, raw)?; + let (buffer, verified) = self.process(&entry, raw)?; Ok(Resource { content_version: entry.content_version, flags: entry.flags, data: buffer.into_boxed_slice(), - authenticated: is_secure, + verified, }) } else { return Err(InternalError::MissingResourceError(id.as_ref().to_string())); @@ -282,7 +282,7 @@ where content_version: entry.content_version, flags: entry.flags, data: buffer.into_boxed_slice(), - authenticated: is_secure, + verified: is_secure, }) } else { return Err(InternalError::MissingResourceError(id.as_ref().to_string())); diff --git a/vach/src/loader/resource.rs b/vach/src/loader/resource.rs index adfa8d2f..045e5102 100644 --- a/vach/src/loader/resource.rs +++ b/vach/src/loader/resource.rs @@ -1,21 +1,17 @@ use std::fmt; use crate::global::flags::Flags; -/// Basically processed data obtained from an archive. -/// Contains `data`, `flags` and `content_version` fields. -/// Is returned by [`archive.fetch(...)`](crate::archive::Archive) -#[non_exhaustive] +/// Basically processed data obtained from an archive returned by [`archive.fetch(...)`](crate::archive::Archive::fetch) and [`archive.fetch_mut(...)`](crate::archive::Archive::fetch_mut) #[derive(Debug)] pub struct Resource { - /// The processed data, stored as a vector of bytes `Vec`. + /// The parsed data pub data: Box<[u8]>, /// The flags extracted from the archive's registry entry pub flags: Flags, - /// The content version of the extracted archive entry + /// The content version of stored in the registry entry pub content_version: u8, - /// A [`Resource`] is checked for authenticity, corruption or obsolescence against it's signature. - /// If the checks pass, then this becomes true, this is always false if the `crypto` feature is off or if the data had no signature - pub authenticated: bool, + /// If a [`Resource's`](Resource) bytes were signed and the signature check passed + pub verified: bool, } impl fmt::Display for Resource { diff --git a/vach/src/tests.rs b/vach/src/tests.rs index 20ea6862..a951aa98 100644 --- a/vach/src/tests.rs +++ b/vach/src/tests.rs @@ -99,7 +99,7 @@ fn builder_no_signature() -> InternalResult { )?; let mut target = File::create(SIMPLE_TARGET)?; - builder.dump(&mut target, &build_config)?; + builder.dump(&mut target, build_config)?; Ok(()) } @@ -112,7 +112,7 @@ fn fetch_no_signature() -> InternalResult { let resource = archive.fetch_mut("wasm")?; assert_eq!(resource.data.len(), 106537); - assert!(!resource.authenticated); + assert!(!resource.verified); assert!(!resource.flags.contains(Flags::COMPRESSED_FLAG)); let hello = archive.fetch_mut("greeting")?; @@ -142,7 +142,7 @@ fn builder_with_signature() -> InternalResult { let mut target = File::create(SIGNED_TARGET)?; println!( "Number of bytes written: {}, into signed archive.", - builder.dump(&mut target, &build_config)? + builder.dump(&mut target, build_config)? ); Ok(()) @@ -165,10 +165,10 @@ fn fetch_with_signature() -> InternalResult { // The adjacent resource was flagged to not be signed let not_signed_resource = archive.fetch_mut("not_signed")?; assert!(!not_signed_resource.flags.contains(Flags::SIGNED_FLAG)); - assert!(!not_signed_resource.authenticated); + assert!(!not_signed_resource.verified); let resource = archive.fetch_mut("signed")?; - assert!(resource.authenticated); + assert!(resource.verified); assert!(resource.flags.contains(Flags::SIGNED_FLAG)); Ok(()) @@ -213,7 +213,7 @@ fn builder_with_encryption() -> InternalResult { let mut target = File::create(ENCRYPTED_TARGET)?; println!( "Number of bytes written: {}, into encrypted and fully compressed archive.", - builder.dump(&mut target, &build_config)? + builder.dump(&mut target, build_config)? ); Ok(()) @@ -239,7 +239,7 @@ fn fetch_from_encrypted() -> InternalResult { let signed = archive.fetch_mut("test_data/quicksort.wasm")?; assert_eq!(signed.data.len(), 106537); - assert!(signed.authenticated); + assert!(signed.verified); assert!(!signed.flags.contains(Flags::COMPRESSED_FLAG)); assert!(signed.flags.contains(Flags::ENCRYPTED_FLAG)); @@ -275,10 +275,10 @@ fn consolidated_example() -> InternalResult { // Dump data let then = Instant::now(); - builder.dump(&mut target, &config)?; + builder.dump(&mut target, config)?; // Just because - println!("Building took: {}us", then.elapsed().as_micros()); + println!("Building took: {:?}", then.elapsed()); // Load data let mut config = ArchiveConfig::default().magic(*MAGIC); @@ -287,7 +287,7 @@ fn consolidated_example() -> InternalResult { let then = Instant::now(); let mut archive = Archive::with_config(target, &config)?; - println!("Archive initialization took: {}us", then.elapsed().as_micros()); + println!("Archive initialization took: {:?}", then.elapsed()); // Quick assertions let then = Instant::now(); @@ -295,7 +295,7 @@ fn consolidated_example() -> InternalResult { assert_eq!(archive.fetch_mut("d2")?.data.as_ref(), data_2); assert_eq!(archive.fetch_mut("d3")?.data.as_ref(), data_3); - println!("Fetching took: {}us on average", then.elapsed().as_micros() / 4u128); + println!("Fetching took: {:?} on average", then.elapsed() / 3); // All seems ok Ok(()) @@ -330,7 +330,7 @@ fn test_compressors() -> InternalResult { .compress(CompressMode::Always), )?; - builder.dump(&mut target, &BuilderConfig::default())?; + builder.dump(&mut target, BuilderConfig::default())?; let mut archive = Archive::new(&mut target)?; @@ -386,7 +386,7 @@ fn test_batch_fetching() -> InternalResult { ids.push("ERRORS".to_string()); // Process data - builder.dump(&mut target, &BuilderConfig::default())?; + builder.dump(&mut target, BuilderConfig::default())?; let archive = Archive::new(target)?; let mut resources = ids diff --git a/vach/src/writer/config.rs b/vach/src/writer/config.rs index e4a893f7..d2b4bae2 100644 --- a/vach/src/writer/config.rs +++ b/vach/src/writer/config.rs @@ -1,5 +1,7 @@ -use crate::global::{flags::Flags, reg_entry::RegistryEntry}; +#[cfg(feature = "multithreaded")] +use std::num::NonZeroUsize; +use crate::global::{flags::Flags, reg_entry::RegistryEntry}; #[cfg(feature = "crypto")] use crate::crypto; @@ -8,15 +10,15 @@ use crate::crypto; pub struct BuilderConfig<'a> { /// Number of threads to spawn during `Builder::dump`, defaults to 4 #[cfg(feature = "multithreaded")] - pub num_threads: usize, - /// Used to write a unique magic sequence into the write target. + pub num_threads: NonZeroUsize, + /// Used to write a unique magic sequence into the archive. pub magic: [u8; crate::MAGIC_LENGTH], - /// Flags to be written into the `Header` section of the write target. + /// Flags to be written into the `Header` section of the archive. pub flags: Flags, - /// An optional keypair. If a key is provided, then the write target will have signatures for tamper verification. + /// An optional private key. If one is provided, then the archive will have signatures. #[cfg(feature = "crypto")] #[cfg_attr(docsrs, doc(cfg(feature = "crypto")))] - pub keypair: Option, + pub signing_key: Option, /// An optional callback that is called every time a [Leaf](crate::builder::Leaf) finishes processing. /// The callback get passed to it: a reference to the leaf and the generated registry entry. Use the RegEntry to get info on how the data was integrated for the given [`Leaf`]. /// > **To avoid** the `implementation of "FnOnce" is not general enough` error consider adding types to the closure's parameters, as this is a type inference error. Rust somehow cannot infer enough information, [link](https://www.reddit.com/r/rust/comments/ntqu68/implementation_of_fnonce_is_not_general_enough/). @@ -25,13 +27,13 @@ pub struct BuilderConfig<'a> { /// use vach::prelude::{RegistryEntry, BuilderConfig, Leaf}; /// /// let builder_config = BuilderConfig::default(); - /// fn callback(reg_entry: &RegistryEntry) { - /// println!("Processed Entry: {:?}", reg_entry) + /// fn callback(reg_entry: &RegistryEntry, data: &[u8]) { + /// println!("Processed Entry: {:?}. First Bytes: {:?}", reg_entry, &data[0..1]) /// } /// - /// builder_config.callback(&callback); + /// builder_config.callback(&mut callback); /// ``` - pub progress_callback: Option<&'a dyn Fn(&RegistryEntry)>, + pub progress_callback: Option<&'a mut dyn FnMut(&RegistryEntry, &[u8])>, } impl<'a> std::fmt::Debug for BuilderConfig<'a> { @@ -50,22 +52,21 @@ impl<'a> std::fmt::Debug for BuilderConfig<'a> { ); #[cfg(feature = "crypto")] - f.field("keypair", &self.keypair); + f.field("keypair", &self.signing_key); f.finish() } } +// Helper functions impl<'a> BuilderConfig<'a> { - // Helper functions /// Setter for the `keypair` field #[cfg(feature = "crypto")] pub fn keypair(mut self, keypair: crypto::SigningKey) -> Self { - self.keypair = Some(keypair); + self.signing_key = Some(keypair); self } - /// Setter for the `flags` field ///``` /// use vach::prelude::{Flags, BuilderConfig}; /// @@ -76,7 +77,6 @@ impl<'a> BuilderConfig<'a> { self } - /// Setter for the `magic` field ///``` /// use vach::prelude::BuilderConfig; /// let config = BuilderConfig::default().magic(*b"DbAfh"); @@ -86,23 +86,21 @@ impl<'a> BuilderConfig<'a> { self } - /// Setter for the `progress_callback` field ///``` /// use vach::prelude::{BuilderConfig, RegistryEntry, Leaf}; /// - /// let callback = |entry: &RegistryEntry| { println!("Number of bytes written: {}", entry.offset) }; - /// let config = BuilderConfig::default().callback(&callback); + /// let mut callback = |entry: &RegistryEntry, _data: &[u8]| { println!("Number of bytes written: {}", entry.offset) }; + /// let config = BuilderConfig::default().callback(&mut callback); ///``` - pub fn callback(mut self, callback: &'a dyn Fn(&RegistryEntry)) -> BuilderConfig<'a> { + pub fn callback(mut self, callback: &'a mut dyn FnMut(&RegistryEntry, &[u8])) -> BuilderConfig<'a> { self.progress_callback = Some(callback); self } - // Keypair helpers - /// Parses and stores a keypair from a source. + /// Read and parse a keypair from a stream of bytes #[cfg(feature = "crypto")] pub fn load_keypair(&mut self, handle: T) -> crate::global::error::InternalResult { - crate::crypto_utils::read_keypair(handle).map(|kp| self.keypair = Some(kp)) + crate::crypto_utils::read_keypair(handle).map(|kp| self.signing_key = Some(kp)) } } @@ -110,12 +108,12 @@ impl<'a> Default for BuilderConfig<'a> { fn default() -> BuilderConfig<'a> { BuilderConfig { #[cfg(feature = "multithreaded")] - num_threads: 4, + num_threads: unsafe { NonZeroUsize::new_unchecked(4) }, flags: Flags::default(), magic: *crate::DEFAULT_MAGIC, progress_callback: None, #[cfg(feature = "crypto")] - keypair: None, + signing_key: None, } } } diff --git a/vach/src/writer/mod.rs b/vach/src/writer/mod.rs index 0152c61e..2ddc5ffb 100644 --- a/vach/src/writer/mod.rs +++ b/vach/src/writer/mod.rs @@ -10,7 +10,6 @@ use std::{thread, sync::mpsc}; mod config; mod leaf; -mod prepared; pub use config::BuilderConfig; pub use leaf::Leaf; @@ -38,6 +37,78 @@ pub struct Builder<'a> { leaf_template: Leaf<'a>, } +// Processed data ready to be inserted into a `Write + Clone` target during Building +pub(crate) struct Prepared { + pub(crate) data: Vec, + pub(crate) entry: RegistryEntry, + #[cfg(feature = "crypto")] + pub(crate) sign: bool, +} + +impl Prepared { + // Process Leaf into Prepared Data, externalised for multithreading purposes + fn from_leaf<'a>(leaf: &mut Leaf<'a>, encryptor: Option<&Encryptor>) -> InternalResult { + let mut entry: RegistryEntry = leaf.into(); + let mut raw = Vec::new(); // 10MB + + // Compression comes first + #[cfg(feature = "compression")] + match leaf.compress { + CompressMode::Never => { + leaf.handle.read_to_end(&mut raw)?; + }, + CompressMode::Always => { + Compressor::new(&mut leaf.handle).compress(leaf.compression_algo, &mut raw)?; + + entry.flags.force_set(Flags::COMPRESSED_FLAG, true); + entry.flags.force_set(leaf.compression_algo.into(), true); + }, + CompressMode::Detect => { + let mut buffer = Vec::new(); + leaf.handle.read_to_end(&mut buffer)?; + + let mut compressed_data = Vec::new(); + Compressor::new(buffer.as_slice()).compress(leaf.compression_algo, &mut compressed_data)?; + + if compressed_data.len() <= buffer.len() { + entry.flags.force_set(Flags::COMPRESSED_FLAG, true); + entry.flags.force_set(leaf.compression_algo.into(), true); + + raw = compressed_data; + } else { + buffer.as_slice().read_to_end(&mut raw)?; + }; + }, + } + + // If the compression feature is turned off, simply reads into buffer + #[cfg(not(feature = "compression"))] + { + if entry.flags.contains(Flags::COMPRESSED_FLAG) { + return Err(InternalError::MissingFeatureError("compression")); + }; + + leaf.handle.read_to_end(&mut raw)?; + } + + // Encryption comes second + #[cfg(feature = "crypto")] + if leaf.encrypt { + if let Some(ex) = encryptor { + raw = ex.encrypt(&raw)?; + entry.flags.force_set(Flags::ENCRYPTED_FLAG, true); + } + } + + Ok(Prepared { + data: raw, + entry, + #[cfg(feature = "crypto")] + sign: leaf.sign, + }) + } +} + impl<'a> Builder<'a> { /// Instantiates a new [`Builder`] with an empty processing queue. #[inline(always)] @@ -113,75 +184,14 @@ impl<'a> Builder<'a> { /// builder.add(b"JEB" as &[u8], "JEB_NAME").unwrap(); /// // `JEB` is compressed and has a version of 12 /// ``` - pub fn template(mut self, template: Leaf<'a>) -> Builder { + pub fn template(mut self, template: Leaf<'a>) -> Builder<'a> { self.leaf_template = template; self } - fn process_leaf(leaf: &mut Leaf<'a>, encryptor: Option<&Encryptor>) -> InternalResult { - let mut entry: RegistryEntry = leaf.into(); - let mut raw = Vec::new(); // 10MB - - // Compression comes first - #[cfg(feature = "compression")] - match leaf.compress { - CompressMode::Never => { - leaf.handle.read_to_end(&mut raw)?; - }, - CompressMode::Always => { - Compressor::new(&mut leaf.handle).compress(leaf.compression_algo, &mut raw)?; - - entry.flags.force_set(Flags::COMPRESSED_FLAG, true); - entry.flags.force_set(leaf.compression_algo.into(), true); - }, - CompressMode::Detect => { - let mut buffer = Vec::new(); - leaf.handle.read_to_end(&mut buffer)?; - - let mut compressed_data = Vec::new(); - Compressor::new(buffer.as_slice()).compress(leaf.compression_algo, &mut compressed_data)?; - - if compressed_data.len() <= buffer.len() { - entry.flags.force_set(Flags::COMPRESSED_FLAG, true); - entry.flags.force_set(leaf.compression_algo.into(), true); - - raw = compressed_data; - } else { - buffer.as_slice().read_to_end(&mut raw)?; - }; - }, - } - - // If the compression feature is turned off, simply reads into buffer - #[cfg(not(feature = "compression"))] - { - if entry.flags.contains(Flags::COMPRESSED_FLAG) { - return Err(InternalError::MissingFeatureError("compression")); - }; - - leaf.handle.read_to_end(&mut raw)?; - } - - // Encryption comes second - #[cfg(feature = "crypto")] - if leaf.encrypt { - if let Some(ex) = encryptor { - raw = ex.encrypt(&raw)?; - entry.flags.force_set(Flags::ENCRYPTED_FLAG, true); - } - } - - Ok(prepared::Prepared { - data: raw, - entry, - #[cfg(feature = "crypto")] - sign: leaf.sign, - }) - } - /// This iterates over all [`Leaf`]s in the processing queue, parses them and writes the bytes out into a the target. /// Configure the custom *`MAGIC`*, `Header` flags and a [`Keypair`](crate::crypto::Keypair) using the [`BuilderConfig`] struct. - pub fn dump(self, mut target: W, config: &BuilderConfig) -> InternalResult { + pub fn dump(self, mut target: W, mut config: BuilderConfig) -> InternalResult { let Builder { mut leafs, .. } = self; // Calculate the size of the registry and check for [`Leaf`]s that request for encryption @@ -193,7 +203,7 @@ impl<'a> Builder<'a> { // The size of it's ID, the minimum size of an entry without a signature, and the size of a signature only if a signature is incorporated into the entry leaf.id.len() + RegistryEntry::MIN_SIZE + { #[cfg(feature = "crypto")] - if config.keypair.is_some() && leaf.sign { + if config.signing_key.is_some() && leaf.sign { crate::SIGNATURE_LENGTH } else { 0 @@ -205,7 +215,8 @@ impl<'a> Builder<'a> { } }) .reduce(|l1, l2| l1 + l2) - .unwrap_or(0) + Header::BASE_SIZE + .unwrap_or(0) + + Header::BASE_SIZE } as u64; // Start at the very start of the file @@ -216,7 +227,7 @@ impl<'a> Builder<'a> { let mut temp = config.flags; #[cfg(feature = "crypto")] - if config.keypair.is_some() { + if config.signing_key.is_some() { temp.force_set(Flags::SIGNED_FLAG, true); }; @@ -230,7 +241,7 @@ impl<'a> Builder<'a> { let encryptor = { let use_encryption = leafs.iter().any(|leaf| leaf.encrypt); if use_encryption { - if let Some(keypair) = config.keypair.as_ref() { + if let Some(keypair) = config.signing_key.as_ref() { Some(Encryptor::new(&keypair.verifying_key(), config.magic)) } else { return Err(InternalError::NoKeypairError); @@ -247,7 +258,7 @@ impl<'a> Builder<'a> { let mut registry = Vec::with_capacity(leaf_offset as usize - Header::BASE_SIZE); #[allow(unused_mut)] - let mut write = |result: InternalResult| -> InternalResult<()> { + let mut write = |result: InternalResult| -> InternalResult<()> { let mut result = result?; let bytes = result.data.len() as u64; @@ -266,7 +277,7 @@ impl<'a> Builder<'a> { // write out registry entry #[cfg(feature = "crypto")] if result.sign { - if let Some(keypair) = &config.keypair { + if let Some(keypair) = &config.signing_key { result.entry.flags.force_set(Flags::SIGNED_FLAG, true); let entry_bytes = result.entry.to_bytes(true)?; @@ -282,7 +293,9 @@ impl<'a> Builder<'a> { registry.write_all(&entry_bytes)?; // Call the progress callback bound within the [`BuilderConfig`] - config.progress_callback.inspect(|c| c(&result.entry)); + if let Some(callback) = config.progress_callback.as_mut() { + callback(&result.entry, &result.data); + } Ok(()) }; @@ -291,10 +304,11 @@ impl<'a> Builder<'a> { let (tx, rx) = mpsc::sync_channel(leafs.len()); #[cfg(feature = "multithreaded")] - { + if !leafs.is_empty() { thread::scope(|s| -> InternalResult<()> { let count = leafs.len(); - let chunk_size = leafs.len() / config.num_threads.min(1); + #[rustfmt::skip] + let chunk_size = if config.num_threads.get() > count { 6 } else { count / config.num_threads }; let chunks = leafs.chunks_mut(chunk_size); let encryptor = encryptor.as_ref(); @@ -305,7 +319,7 @@ impl<'a> Builder<'a> { s.spawn(move || { for leaf in chunk { - let res = Builder::process_leaf(leaf, encryptor); + let res = Prepared::from_leaf(leaf, encryptor); queue.send(res).unwrap(); } }); @@ -335,7 +349,7 @@ impl<'a> Builder<'a> { #[cfg(not(feature = "multithreaded"))] leafs .iter_mut() - .map(|l| Builder::process_leaf(l, encryptor.as_ref())) + .map(|l| Prepared::from_leaf(l, encryptor.as_ref())) .try_for_each(write)?; // write out Registry diff --git a/vach/src/writer/prepared.rs b/vach/src/writer/prepared.rs index 056d09b9..e69de29b 100644 --- a/vach/src/writer/prepared.rs +++ b/vach/src/writer/prepared.rs @@ -1,7 +0,0 @@ -// Unit of data ready to be inserted into a `Write + Clone` target during Building -pub(crate) struct Prepared { - pub(crate) data: Vec, - pub(crate) entry: super::RegistryEntry, - #[cfg(feature = "crypto")] - pub(crate) sign: bool, -} diff --git a/vach/test_data/encrypted/target.vach b/vach/test_data/encrypted/target.vach index 0677ee17..dae765f9 100644 Binary files a/vach/test_data/encrypted/target.vach and b/vach/test_data/encrypted/target.vach differ diff --git a/vach/test_data/signed/target.vach b/vach/test_data/signed/target.vach index f9c5e2ee..734aa8df 100644 Binary files a/vach/test_data/signed/target.vach and b/vach/test_data/signed/target.vach differ diff --git a/vach/test_data/simple/target.vach b/vach/test_data/simple/target.vach index 749e4905..2f6b6fac 100644 Binary files a/vach/test_data/simple/target.vach and b/vach/test_data/simple/target.vach differ