diff --git a/Cargo.lock b/Cargo.lock index effd71b9f837..66f3c0d5e72e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -282,6 +282,25 @@ dependencies = [ "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "block-buffer" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-padding 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "block-padding" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "boxfnonce" version = "0.0.3" @@ -297,6 +316,11 @@ name = "byte-tools" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "byte-tools" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byteorder" version = "1.2.1" @@ -728,6 +752,14 @@ dependencies = [ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "digest" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "dirs" version = "1.0.4" @@ -1012,6 +1044,14 @@ dependencies = [ "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "generic-array" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "gkrust" version = "0.1.0" @@ -1765,6 +1805,11 @@ dependencies = [ "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "opaque-debug" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ordered-float" version = "1.0.1" @@ -2266,6 +2311,17 @@ dependencies = [ "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "simd" version = "0.2.3" @@ -2944,7 +3000,7 @@ dependencies = [ "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3130,9 +3186,12 @@ dependencies = [ "checksum bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80b13e2ab064ff3aa0bdbf1eff533f9822dc37899821f5f98c67f263eab51707" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" "checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" +"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" +"checksum block-padding 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc4358306e344bf9775d0197fd00d2603e5afb0771bb353538630f022068ea3" "checksum boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8380105befe91099e6f69206164072c05bc92427ff6aa8a5171388317346dd75" "checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" +"checksum byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "980479e6fde23246dfb54d47580d66b4e99202e7579c5eaa9fe10ecb5ebd2182" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" "checksum bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e178b8e0e239e844b083d5a0d4a156b2654e67f9f80144d48398fcd736a24fb8" "checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24" @@ -3179,6 +3238,7 @@ dependencies = [ "checksum devd-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e7c9ac481c38baf400d3b732e4a06850dfaa491d1b6379a249d9d40d14c2434c" "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" +"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" "checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a" "checksum docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d8acd393692c503b168471874953a2531df0e9ab77d0b6bbc582395743300a4a" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" @@ -3206,6 +3266,7 @@ dependencies = [ "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" +"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" "checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum gl_generator 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a0ffaf173cf76c73a73e080366bf556b4776ece104b06961766ff11449f38604" "checksum gleam 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4b47f5b15742aee359c7895ab98cf2cceecc89bb4feb6f4e42f802d7899877da" @@ -3265,6 +3326,7 @@ dependencies = [ "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" "checksum object 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cca6ad89d0801138cb4ef606908ae12d83edc4c790ef5178fc7b4c72d959e90" +"checksum opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "51ecbcb821e1bd256d456fe858aaa7f380b63863eab2eb86eee1bd9f33dd6682" "checksum ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0015e9e8e28ee20c581cfbfe47c650cedeb9ed0721090e0b7ebb10b9cdbcc2" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" @@ -3320,6 +3382,7 @@ dependencies = [ "checksum serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)" = "" "checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae" "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0" +"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" "checksum simd 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0048b17eb9577ac545c61d85c3559b41dfb4cbea41c9bd9ca6a4f73ff05fda84" "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" diff --git a/third_party/rust/block-buffer-0.3.3/.cargo-checksum.json b/third_party/rust/block-buffer-0.3.3/.cargo-checksum.json new file mode 100644 index 000000000000..97c5faad9543 --- /dev/null +++ b/third_party/rust/block-buffer-0.3.3/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"373908618d7bdf561f84ddc5add92f69dab295c97ab0908d3a4ec428fad23bad","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/lib.rs":"bdf23c8a00fb4d51beabeb6600fe45ebf1be618632db885013b6f60a5666c124","src/paddings.rs":"7a18850dab9dca0a3e6cc49d6a94a9566ea2473628f42f726a69f8e07f95872a"},"package":"a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"} \ No newline at end of file diff --git a/third_party/rust/block-buffer-0.3.3/Cargo.toml b/third_party/rust/block-buffer-0.3.3/Cargo.toml new file mode 100644 index 000000000000..81515f96716b --- /dev/null +++ b/third_party/rust/block-buffer-0.3.3/Cargo.toml @@ -0,0 +1,27 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "block-buffer" +version = "0.3.3" +authors = ["RustCrypto Developers"] +description = "Fixed size buffer for block processing of data" +documentation = "https://docs.rs/block-buffer" +keywords = ["block", "padding", "pkcs7", "ansix923", "iso7816"] +categories = ["cryptography", "no-std"] +license = "MIT/Apache-2.0" +repository = "https://github.com/RustCrypto/utils" +[dependencies.arrayref] +version = "0.3" + +[dependencies.byte-tools] +version = "0.2" diff --git a/third_party/rust/block-buffer-0.3.3/LICENSE-APACHE b/third_party/rust/block-buffer-0.3.3/LICENSE-APACHE new file mode 100644 index 000000000000..78173fa2e753 --- /dev/null +++ b/third_party/rust/block-buffer-0.3.3/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/block-buffer-0.3.3/LICENSE-MIT b/third_party/rust/block-buffer-0.3.3/LICENSE-MIT new file mode 100644 index 000000000000..8dcb85b30273 --- /dev/null +++ b/third_party/rust/block-buffer-0.3.3/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2017 Artyom Pavlov + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/block-buffer-0.3.3/src/lib.rs b/third_party/rust/block-buffer-0.3.3/src/lib.rs new file mode 100644 index 000000000000..7f5c8af2c984 --- /dev/null +++ b/third_party/rust/block-buffer-0.3.3/src/lib.rs @@ -0,0 +1,144 @@ +#![no_std] +#[macro_use] +extern crate arrayref; +extern crate byte_tools; + +use byte_tools::{zero, write_u64_le}; + +mod paddings; + +pub use paddings::*; + +macro_rules! impl_buffer { + ($name:ident, $len:expr) => { + + pub struct $name { + buffer: [u8; $len], + pos: usize, + } + + impl Copy for $name {} + + impl Clone for $name { + fn clone(&self) -> Self { + *self + } + } + + impl Default for $name { + fn default() -> Self { + $name {buffer: [0; $len], pos: 0} + } + } + + impl $name { + #[inline] + pub fn input(&mut self, mut input: &[u8], mut func: F) { + // If there is already data in the buffer, copy as much as we can + // into it and process the data if the buffer becomes full. + if self.pos != 0 { + let rem = self.remaining(); + + if input.len() >= rem { + let (l, r) = input.split_at(rem); + input = r; + self.buffer[self.pos..].copy_from_slice(l); + self.pos = 0; + func(&self.buffer); + } else { + let end = self.pos + input.len(); + self.buffer[self.pos..end].copy_from_slice(input); + self.pos = end; + return; + } + } + + // While we have at least a full buffer size chunks's worth of data, + // process that data without copying it into the buffer + while input.len() >= self.size() { + let (l, r) = input.split_at(self.size()); + input = r; + func(array_ref!(l, 0, $len)); + } + + // Copy any input data into the buffer. At this point in the method, + // the ammount of data left in the input vector will be less than + // the buffer size and the buffer will be empty. + self.buffer[..input.len()].copy_from_slice(input); + self.pos = input.len(); + } + + #[inline] + fn digest_pad(&mut self, up_to: usize, func: &mut F) + where F: FnMut(&[u8; $len]) + { + self.buffer[self.pos] = 0x80; + self.pos += 1; + + zero(&mut self.buffer[self.pos..]); + + if self.remaining() < up_to { + func(&self.buffer); + zero(&mut self.buffer[..self.pos]); + } + } + + #[inline] + /// Will pad message with message length in big-endian format + pub fn len_padding(&mut self, data_len: u64, mut func: F) + where F: FnMut(&[u8; $len]) + { + self.digest_pad(8, &mut func); + let s = self.size(); + write_u64_le(&mut self.buffer[s-8..], data_len); + func(&self.buffer); + self.pos = 0; + } + + #[inline] + pub fn len_padding_u128(&mut self, hi: u64, lo: u64, mut func: F) + where F: FnMut(&[u8; $len]) + { + self.digest_pad(16, &mut func); + let s = self.size(); + write_u64_le(&mut self.buffer[s-16..s-8], hi); + write_u64_le(&mut self.buffer[s-8..], lo); + func(&self.buffer); + self.pos = 0; + } + + #[inline] + pub fn pad_with(&mut self) -> &mut [u8; $len] { + P::pad(&mut self.buffer[..], self.pos); + self.pos = 0; + &mut self.buffer + } + + #[inline] + pub fn size(&self) -> usize { + $len + } + + #[inline] + pub fn position(&self) -> usize { + self.pos + } + + #[inline] + pub fn remaining(&self) -> usize { + self.size() - self.pos + } + } + } +} + +impl_buffer!(BlockBuffer128, 16); +impl_buffer!(BlockBuffer256, 32); +impl_buffer!(BlockBuffer512, 64); +impl_buffer!(BlockBuffer1024, 128); + +impl_buffer!(BlockBuffer576, 72); +impl_buffer!(BlockBuffer832, 104); +impl_buffer!(BlockBuffer1088, 136); +impl_buffer!(BlockBuffer1152, 144); +impl_buffer!(BlockBuffer1344, 168); diff --git a/third_party/rust/block-buffer/src/paddings.rs b/third_party/rust/block-buffer-0.3.3/src/paddings.rs similarity index 100% rename from third_party/rust/block-buffer/src/paddings.rs rename to third_party/rust/block-buffer-0.3.3/src/paddings.rs diff --git a/third_party/rust/block-buffer/.cargo-checksum.json b/third_party/rust/block-buffer/.cargo-checksum.json index 97c5faad9543..9963efa899c6 100644 --- a/third_party/rust/block-buffer/.cargo-checksum.json +++ b/third_party/rust/block-buffer/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"373908618d7bdf561f84ddc5add92f69dab295c97ab0908d3a4ec428fad23bad","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/lib.rs":"bdf23c8a00fb4d51beabeb6600fe45ebf1be618632db885013b6f60a5666c124","src/paddings.rs":"7a18850dab9dca0a3e6cc49d6a94a9566ea2473628f42f726a69f8e07f95872a"},"package":"a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"} \ No newline at end of file +{"files":{"Cargo.toml":"1f13fcd2c3ee3e1a47b5f1519a9840f6fc00a6c9b54ad29697e6120e3756f4b8","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/lib.rs":"13262364125a588d9cd179e1bd24a3286f8778b8d3f11fc86cce605939ebe5b1"},"package":"49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d"} \ No newline at end of file diff --git a/third_party/rust/block-buffer/Cargo.toml b/third_party/rust/block-buffer/Cargo.toml index 81515f96716b..1749ebe6806f 100644 --- a/third_party/rust/block-buffer/Cargo.toml +++ b/third_party/rust/block-buffer/Cargo.toml @@ -12,16 +12,25 @@ [package] name = "block-buffer" -version = "0.3.3" +version = "0.7.0" authors = ["RustCrypto Developers"] description = "Fixed size buffer for block processing of data" documentation = "https://docs.rs/block-buffer" -keywords = ["block", "padding", "pkcs7", "ansix923", "iso7816"] +keywords = ["block", "buffer"] categories = ["cryptography", "no-std"] license = "MIT/Apache-2.0" repository = "https://github.com/RustCrypto/utils" -[dependencies.arrayref] -version = "0.3" +[dependencies.block-padding] +version = "0.1" [dependencies.byte-tools] -version = "0.2" +version = "0.3" + +[dependencies.byteorder] +version = "1" +default-features = false + +[dependencies.generic-array] +version = "0.12" +[badges.travis-ci] +repository = "RustCrypto/utils" diff --git a/third_party/rust/block-buffer/src/lib.rs b/third_party/rust/block-buffer/src/lib.rs index 7f5c8af2c984..f8b541066b1f 100644 --- a/third_party/rust/block-buffer/src/lib.rs +++ b/third_party/rust/block-buffer/src/lib.rs @@ -1,144 +1,170 @@ #![no_std] -#[macro_use] -extern crate arrayref; +pub extern crate byteorder; +pub extern crate block_padding; +pub extern crate generic_array; extern crate byte_tools; -use byte_tools::{zero, write_u64_le}; +use byteorder::{ByteOrder, BE}; +use byte_tools::zero; +use block_padding::{Padding, PadError}; +use generic_array::{GenericArray, ArrayLength}; -mod paddings; - -pub use paddings::*; - -macro_rules! impl_buffer { - ($name:ident, $len:expr) => { - - pub struct $name { - buffer: [u8; $len], - pos: usize, - } - - impl Copy for $name {} - - impl Clone for $name { - fn clone(&self) -> Self { - *self - } - } - - impl Default for $name { - fn default() -> Self { - $name {buffer: [0; $len], pos: 0} - } - } - - impl $name { - #[inline] - pub fn input(&mut self, mut input: &[u8], mut func: F) { - // If there is already data in the buffer, copy as much as we can - // into it and process the data if the buffer becomes full. - if self.pos != 0 { - let rem = self.remaining(); - - if input.len() >= rem { - let (l, r) = input.split_at(rem); - input = r; - self.buffer[self.pos..].copy_from_slice(l); - self.pos = 0; - func(&self.buffer); - } else { - let end = self.pos + input.len(); - self.buffer[self.pos..end].copy_from_slice(input); - self.pos = end; - return; - } - } - - // While we have at least a full buffer size chunks's worth of data, - // process that data without copying it into the buffer - while input.len() >= self.size() { - let (l, r) = input.split_at(self.size()); - input = r; - func(array_ref!(l, 0, $len)); - } - - // Copy any input data into the buffer. At this point in the method, - // the ammount of data left in the input vector will be less than - // the buffer size and the buffer will be empty. - self.buffer[..input.len()].copy_from_slice(input); - self.pos = input.len(); - } - - #[inline] - fn digest_pad(&mut self, up_to: usize, func: &mut F) - where F: FnMut(&[u8; $len]) - { - self.buffer[self.pos] = 0x80; - self.pos += 1; - - zero(&mut self.buffer[self.pos..]); - - if self.remaining() < up_to { - func(&self.buffer); - zero(&mut self.buffer[..self.pos]); - } - } - - #[inline] - /// Will pad message with message length in big-endian format - pub fn len_padding(&mut self, data_len: u64, mut func: F) - where F: FnMut(&[u8; $len]) - { - self.digest_pad(8, &mut func); - let s = self.size(); - write_u64_le(&mut self.buffer[s-8..], data_len); - func(&self.buffer); - self.pos = 0; - } - - #[inline] - pub fn len_padding_u128(&mut self, hi: u64, lo: u64, mut func: F) - where F: FnMut(&[u8; $len]) - { - self.digest_pad(16, &mut func); - let s = self.size(); - write_u64_le(&mut self.buffer[s-16..s-8], hi); - write_u64_le(&mut self.buffer[s-8..], lo); - func(&self.buffer); - self.pos = 0; - } - - #[inline] - pub fn pad_with(&mut self) -> &mut [u8; $len] { - P::pad(&mut self.buffer[..], self.pos); - self.pos = 0; - &mut self.buffer - } - - #[inline] - pub fn size(&self) -> usize { - $len - } - - #[inline] - pub fn position(&self) -> usize { - self.pos - } - - #[inline] - pub fn remaining(&self) -> usize { - self.size() - self.pos - } - } - } +/// Buffer for block processing of data +#[derive(Clone, Default)] +pub struct BlockBuffer> { + buffer: GenericArray, + pos: usize, } -impl_buffer!(BlockBuffer128, 16); -impl_buffer!(BlockBuffer256, 32); -impl_buffer!(BlockBuffer512, 64); -impl_buffer!(BlockBuffer1024, 128); +#[inline(always)] +unsafe fn cast>(block: &[u8]) -> &GenericArray { + debug_assert_eq!(block.len(), N::to_usize()); + &*(block.as_ptr() as *const GenericArray) +} -impl_buffer!(BlockBuffer576, 72); -impl_buffer!(BlockBuffer832, 104); -impl_buffer!(BlockBuffer1088, 136); -impl_buffer!(BlockBuffer1152, 144); -impl_buffer!(BlockBuffer1344, 168); +impl> BlockBuffer { + /// Process data in `input` in blocks of size `BlockSize` using function `f`. + #[inline] + pub fn input(&mut self, mut input: &[u8], mut f: F) + where F: FnMut(&GenericArray) + { + // If there is already data in the buffer, process it if we have + // enough to complete the chunk. + let rem = self.remaining(); + if self.pos != 0 && input.len() >= rem { + let (l, r) = input.split_at(rem); + input = r; + self.buffer[self.pos..].copy_from_slice(l); + self.pos = 0; + f(&self.buffer); + } + + // While we have at least a full buffer size chunks's worth of data, + // process that data without copying it into the buffer + while input.len() >= self.size() { + let (block, r) = input.split_at(self.size()); + input = r; + f(unsafe { cast(block) }); + } + + // Copy any remaining data into the buffer. + self.buffer[self.pos..self.pos+input.len()].copy_from_slice(input); + self.pos += input.len(); + } + + /// Variant that doesn't flush the buffer until there's additional + /// data to be processed. Suitable for tweakable block ciphers + /// like Threefish that need to know whether a block is the *last* + /// data block before processing it. + #[inline] + pub fn input_lazy(&mut self, mut input: &[u8], mut f: F) + where F: FnMut(&GenericArray) + { + let rem = self.remaining(); + if self.pos != 0 && input.len() > rem { + let (l, r) = input.split_at(rem); + input = r; + self.buffer[self.pos..].copy_from_slice(l); + self.pos = 0; + f(&self.buffer); + } + + while input.len() > self.size() { + let (block, r) = input.split_at(self.size()); + input = r; + f(unsafe { cast(block) }); + } + + self.buffer[self.pos..self.pos+input.len()].copy_from_slice(input); + self.pos += input.len(); + } + + /// Pad buffer with `prefix` and make sure that internall buffer + /// has at least `up_to` free bytes. All remaining bytes get + /// zeroed-out. + #[inline] + fn digest_pad(&mut self, up_to: usize, f: &mut F) + where F: FnMut(&GenericArray) + { + if self.pos == self.size() { + f(&self.buffer); + self.pos = 0; + } + self.buffer[self.pos] = 0x80; + self.pos += 1; + + zero(&mut self.buffer[self.pos..]); + + if self.remaining() < up_to { + f(&self.buffer); + zero(&mut self.buffer[..self.pos]); + } + } + + /// Pad message with 0x80, zeros and 64-bit message length + /// in a byte order specified by `B` + #[inline] + pub fn len64_padding(&mut self, data_len: u64, mut f: F) + where B: ByteOrder, F: FnMut(&GenericArray) + { + // TODO: replace `F` with `impl Trait` on MSRV bump + self.digest_pad(8, &mut f); + let s = self.size(); + B::write_u64(&mut self.buffer[s-8..], data_len); + f(&self.buffer); + self.pos = 0; + } + + + /// Pad message with 0x80, zeros and 128-bit message length + /// in the big-endian byte order + #[inline] + pub fn len128_padding_be(&mut self, hi: u64, lo: u64, mut f: F) + where F: FnMut(&GenericArray) + { + // TODO: on MSRV bump replace `F` with `impl Trait`, use `u128`, add `B` + self.digest_pad(16, &mut f); + let s = self.size(); + BE::write_u64(&mut self.buffer[s-16..s-8], hi); + BE::write_u64(&mut self.buffer[s-8..], lo); + f(&self.buffer); + self.pos = 0; + } + + /// Pad message with a given padding `P` + /// + /// Returns `PadError` if internall buffer is full, which can only happen if + /// `input_lazy` was used. + #[inline] + pub fn pad_with(&mut self) + -> Result<&mut GenericArray, PadError> + { + P::pad_block(&mut self.buffer[..], self.pos)?; + self.pos = 0; + Ok(&mut self.buffer) + } + + /// Return size of the internall buffer in bytes + #[inline] + pub fn size(&self) -> usize { + BlockSize::to_usize() + } + + /// Return current cursor position + #[inline] + pub fn position(&self) -> usize { + self.pos + } + + /// Return number of remaining bytes in the internall buffer + #[inline] + pub fn remaining(&self) -> usize { + self.size() - self.pos + } + + /// Reset buffer by setting cursor position to zero + #[inline] + pub fn reset(&mut self) { + self.pos = 0 + } +} diff --git a/third_party/rust/block-padding/.cargo-checksum.json b/third_party/rust/block-padding/.cargo-checksum.json new file mode 100644 index 000000000000..21e018875784 --- /dev/null +++ b/third_party/rust/block-padding/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"31334ebd0923996ae8fb76ee87f9b2d75cc9e85c5126ef614e184af56dd96403","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"f7e8ab639afef15573680c97f796166835cbeb3865175882fea41c60d106b733","src/lib.rs":"812d9b3b472539aa4cc78745313d088879aafa8d1baa69872bc1ca8ee5bcfa41"},"package":"4fc4358306e344bf9775d0197fd00d2603e5afb0771bb353538630f022068ea3"} \ No newline at end of file diff --git a/third_party/rust/block-padding/Cargo.toml b/third_party/rust/block-padding/Cargo.toml new file mode 100644 index 000000000000..8dff8401de2a --- /dev/null +++ b/third_party/rust/block-padding/Cargo.toml @@ -0,0 +1,26 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "block-padding" +version = "0.1.2" +authors = ["RustCrypto Developers"] +description = "Padding and unpadding of messages divided into blocks." +documentation = "https://docs.rs/block-padding" +keywords = ["padding", "pkcs7", "ansix923", "iso7816"] +categories = ["cryptography", "no-std"] +license = "MIT/Apache-2.0" +repository = "https://github.com/RustCrypto/utils" +[dependencies.byte-tools] +version = "0.3" +[badges.travis-ci] +repository = "RustCrypto/utils" diff --git a/third_party/rust/block-padding/LICENSE-APACHE b/third_party/rust/block-padding/LICENSE-APACHE new file mode 100644 index 000000000000..78173fa2e753 --- /dev/null +++ b/third_party/rust/block-padding/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/block-padding/LICENSE-MIT b/third_party/rust/block-padding/LICENSE-MIT new file mode 100644 index 000000000000..f5b157a6cfb7 --- /dev/null +++ b/third_party/rust/block-padding/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2018 Artyom Pavlov + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/block-padding/src/lib.rs b/third_party/rust/block-padding/src/lib.rs new file mode 100644 index 000000000000..c088d80f9626 --- /dev/null +++ b/third_party/rust/block-padding/src/lib.rs @@ -0,0 +1,276 @@ +//! Padding and unpadding of messages divided into blocks. +//! +//! This crate provides `Padding` trait which provides padding and unpadding +//! operations. Additionally several common padding schemes are available out +//! of the box. +#![no_std] +#![doc(html_logo_url = + "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +extern crate byte_tools; + +use byte_tools::{zero, set}; + +/// Error for indicating failed padding operation +#[derive(Clone, Copy, Debug)] +pub struct PadError; + +/// Error for indicating failed unpadding operation +#[derive(Clone, Copy, Debug)] +pub struct UnpadError; + +/// Trait for padding messages divided into blocks +pub trait Padding { + /// Pads `block` filled with data up to `pos`. + /// + /// `pos` should be inside of the block and block must not be full, i.e. + /// `pos < block.len()` must be true. Otherwise method will return + /// `PadError`. Some potentially irreversible padding schemes can allow + /// padding of the full block, in this case aforementioned condition is + /// relaxed to `pos <= block.len()`. + fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError>; + + /// Pads message with length `pos` in the provided buffer. + /// + /// `&buf[..pos]` is percieved as the message, buffer must contain at + /// least one block of leftover space, i.e. `buf.len() - pos >= block_size` + /// must be true. Otherwise method will return `PadError`. + fn pad(buf: &mut [u8], pos: usize, block_size: usize) + -> Result<&mut [u8], PadError> + { + if buf.len() - pos < block_size { Err(PadError)? } + if pos % block_size == 0 { + Self::pad_block(&mut buf[pos..pos + block_size], 0)?; + Ok(&mut buf[..pos+block_size]) + } else { + let bs = block_size * (pos / block_size); + Self::pad_block(&mut buf[bs..bs+block_size], pos - bs)?; + Ok(&mut buf[..bs+block_size]) + } + } + + /// Unpad given `data` by truncating it according to the used padding. + /// In case of the malformed padding will return `UnpadError` + fn unpad(data: &[u8]) -> Result<&[u8], UnpadError>; +} + +/// Pad block with zeros. +/// +/// ``` +/// use block_padding::{ZeroPadding, Padding}; +/// +/// let msg = b"test"; +/// let n = msg.len(); +/// let mut buffer = [0xff; 16]; +/// buffer[..n].copy_from_slice(msg); +/// let padded_msg = ZeroPadding::pad(&mut buffer, n, 8).unwrap(); +/// assert_eq!(padded_msg, b"test\x00\x00\x00\x00"); +/// assert_eq!(ZeroPadding::unpad(&padded_msg).unwrap(), msg); +/// ``` +/// ``` +/// # use block_padding::{ZeroPadding, Padding}; +/// # let msg = b"test"; +/// # let n = msg.len(); +/// # let mut buffer = [0xff; 16]; +/// # buffer[..n].copy_from_slice(msg); +/// let padded_msg = ZeroPadding::pad(&mut buffer, n, 2).unwrap(); +/// assert_eq!(padded_msg, b"test"); +/// assert_eq!(ZeroPadding::unpad(&padded_msg).unwrap(), msg); +/// ``` +/// +/// Note that zero padding may not be reversible if the original message ends +/// with one or more zero bytes. +pub enum ZeroPadding{} + +impl Padding for ZeroPadding { + fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError> { + if pos > block.len() { Err(PadError)? } + zero(&mut block[pos..]); + Ok(()) + } + + fn pad(buf: &mut [u8], pos: usize, block_size: usize) + -> Result<&mut [u8], PadError> + { + if pos % block_size == 0 { + Ok(&mut buf[..pos]) + } else { + let bs = block_size * (pos / block_size); + let be = bs + block_size; + if buf.len() < be { Err(PadError)? } + Self::pad_block(&mut buf[bs..be], pos - bs)?; + Ok(&mut buf[..be]) + } + } + + fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> { + let mut n = data.len() - 1; + while n != 0 { + if data[n] != 0 { + break; + } + n -= 1; + } + Ok(&data[..n+1]) + } +} + +/// Pad block with bytes with value equal to the number of bytes added. +/// +/// PKCS#7 described in the [RFC 5652](https://tools.ietf.org/html/rfc5652#section-6.3). +/// +/// ``` +/// use block_padding::{Pkcs7, Padding}; +/// +/// let msg = b"test"; +/// let n = msg.len(); +/// let mut buffer = [0xff; 16]; +/// buffer[..n].copy_from_slice(msg); +/// let padded_msg = Pkcs7::pad(&mut buffer, n, 8).unwrap(); +/// assert_eq!(padded_msg, b"test\x04\x04\x04\x04"); +/// assert_eq!(Pkcs7::unpad(&padded_msg).unwrap(), msg); +/// ``` +/// ``` +/// # use block_padding::{Pkcs7, Padding}; +/// # let msg = b"test"; +/// # let n = msg.len(); +/// # let mut buffer = [0xff; 16]; +/// # buffer[..n].copy_from_slice(msg); +/// let padded_msg = Pkcs7::pad(&mut buffer, n, 2).unwrap(); +/// assert_eq!(padded_msg, b"test\x02\x02"); +/// assert_eq!(Pkcs7::unpad(&padded_msg).unwrap(), msg); +/// ``` +/// ``` +/// # use block_padding::{Pkcs7, Padding}; +/// # let buffer = [0xff; 16]; +/// assert!(Pkcs7::unpad(&buffer).is_err()); +/// ``` +/// +/// In addition to conditions stated in the `Padding` trait documentation, +/// `pad_block` will return `PadError` if `block.len() > 255`, and in case of +/// `pad` if `block_size > 255`. +pub enum Pkcs7{} + +impl Padding for Pkcs7 { + fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError> { + if block.len() > 255 { Err(PadError)? } + if pos >= block.len() { Err(PadError)? } + let n = block.len() - pos; + set(&mut block[pos..], n as u8); + Ok(()) + } + + fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> { + if data.is_empty() { Err(UnpadError)? } + let l = data.len(); + let n = data[l-1]; + if n == 0 || n as usize > l { Err(UnpadError)? } + for v in &data[l-n as usize..l-1] { + if *v != n { Err(UnpadError)? } + } + Ok(&data[..l - n as usize]) + } +} + +/// Pad block with zeros excpet the last byte which will be set to the number +/// bytes. +/// +/// ``` +/// use block_padding::{AnsiX923, Padding}; +/// +/// let msg = b"test"; +/// let n = msg.len(); +/// let mut buffer = [0xff; 16]; +/// buffer[..n].copy_from_slice(msg); +/// let padded_msg = AnsiX923::pad(&mut buffer, n, 8).unwrap(); +/// assert_eq!(padded_msg, b"test\x00\x00\x00\x04"); +/// assert_eq!(AnsiX923::unpad(&padded_msg).unwrap(), msg); +/// ``` +/// ``` +/// # use block_padding::{AnsiX923, Padding}; +/// # let msg = b"test"; +/// # let n = msg.len(); +/// # let mut buffer = [0xff; 16]; +/// # buffer[..n].copy_from_slice(msg); +/// let padded_msg = AnsiX923::pad(&mut buffer, n, 2).unwrap(); +/// assert_eq!(padded_msg, b"test\x00\x02"); +/// assert_eq!(AnsiX923::unpad(&padded_msg).unwrap(), msg); +/// ``` +/// ``` +/// # use block_padding::{AnsiX923, Padding}; +/// # let buffer = [0xff; 16]; +/// assert!(AnsiX923::unpad(&buffer).is_err()); +/// ``` +/// +/// In addition to conditions stated in the `Padding` trait documentation, +/// `pad_block` will return `PadError` if `block.len() > 255`, and in case of +/// `pad` if `block_size > 255`. +pub enum AnsiX923{} + +impl Padding for AnsiX923 { + fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError>{ + if block.len() > 255 { Err(PadError)? } + if pos >= block.len() { Err(PadError)? } + let bs = block.len(); + zero(&mut block[pos..bs-1]); + block[bs-1] = (bs - pos) as u8; + Ok(()) + } + + fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> { + if data.is_empty() { Err(UnpadError)? } + let l = data.len(); + let n = data[l-1] as usize; + if n == 0 || n > l { + return Err(UnpadError) + } + for v in &data[l-n..l-1] { + if *v != 0 { Err(UnpadError)? } + } + Ok(&data[..l-n]) + } +} + +/// Pad block with byte sequence `\x80 00...00 00`. +/// +/// ``` +/// use block_padding::{Iso7816, Padding}; +/// +/// let msg = b"test"; +/// let n = msg.len(); +/// let mut buffer = [0xff; 16]; +/// buffer[..n].copy_from_slice(msg); +/// let padded_msg = Iso7816::pad(&mut buffer, n, 8).unwrap(); +/// assert_eq!(padded_msg, b"test\x80\x00\x00\x00"); +/// assert_eq!(Iso7816::unpad(&padded_msg).unwrap(), msg); +/// ``` +/// ``` +/// # use block_padding::{Iso7816, Padding}; +/// # let msg = b"test"; +/// # let n = msg.len(); +/// # let mut buffer = [0xff; 16]; +/// # buffer[..n].copy_from_slice(msg); +/// let padded_msg = Iso7816::pad(&mut buffer, n, 2).unwrap(); +/// assert_eq!(padded_msg, b"test\x80\x00"); +/// assert_eq!(Iso7816::unpad(&padded_msg).unwrap(), msg); +/// ``` +pub enum Iso7816{} + +impl Padding for Iso7816 { + fn pad_block(block: &mut [u8], pos: usize) -> Result<(), PadError> { + if pos >= block.len() { Err(PadError)? } + block[pos] = 0x80; + zero(&mut block[pos+1..]); + Ok(()) + } + + fn unpad(data: &[u8]) -> Result<&[u8], UnpadError> { + if data.is_empty() { Err(UnpadError)? } + let mut n = data.len() - 1; + while n != 0 { + if data[n] != 0 { break; } + n -= 1; + } + if data[n] != 0x80 { Err(UnpadError)? } + Ok(&data[..n]) + } +} diff --git a/third_party/rust/byte-tools-0.2.0/.cargo-checksum.json b/third_party/rust/byte-tools-0.2.0/.cargo-checksum.json new file mode 100644 index 000000000000..0e07b2def735 --- /dev/null +++ b/third_party/rust/byte-tools-0.2.0/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"af6af6ea1dfa296af5dc58986d1afb46952328588069ec0b08723db439e9972d","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"52232c2cee3bb7d8cabe47ef367f1bf8bb607c22bdfca0219d6156cb7f446e9d","src/lib.rs":"9c96cffef7458fc7bd9e4e61270b69d539ff3a9225a0319b7996155c25ff96ab","src/read_single.rs":"3ab78b15754c2a7848a1be871ff6ee2a31a099f8f4f89be44ad210cda0dbcc9a","src/read_slice.rs":"b3790f2fd080db97e239c05c63da123ea375fb9b354dc9cacb859ed9c44f552e","src/write_single.rs":"1cee4f2f5d8690e47840ea7017539ead417a26abc0717137442a6d9d2875afe4","src/write_slice.rs":"de90e6b9cfca67125871bee7cef55c63574b1871a6584e51fc00a97e5877fe69"},"package":"560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"} \ No newline at end of file diff --git a/third_party/rust/byte-tools-0.2.0/Cargo.toml b/third_party/rust/byte-tools-0.2.0/Cargo.toml new file mode 100644 index 000000000000..32bf0cedc2be --- /dev/null +++ b/third_party/rust/byte-tools-0.2.0/Cargo.toml @@ -0,0 +1,21 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "byte-tools" +version = "0.2.0" +authors = ["The Rust-Crypto Project Developers"] +description = "Utility functions for working with bytes" +documentation = "https://docs.rs/byte-tools" +keywords = ["bytes"] +license = "MIT/Apache-2.0" +repository = "https://github.com/RustCrypto/utils" diff --git a/third_party/rust/byte-tools-0.2.0/LICENSE-APACHE b/third_party/rust/byte-tools-0.2.0/LICENSE-APACHE new file mode 100644 index 000000000000..78173fa2e753 --- /dev/null +++ b/third_party/rust/byte-tools-0.2.0/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/byte-tools-0.2.0/LICENSE-MIT b/third_party/rust/byte-tools-0.2.0/LICENSE-MIT new file mode 100644 index 000000000000..1da3a5f6d2e6 --- /dev/null +++ b/third_party/rust/byte-tools-0.2.0/LICENSE-MIT @@ -0,0 +1,26 @@ +Copyright (c) 2006-2009 Graydon Hoare +Copyright (c) 2009-2013 Mozilla Foundation + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/byte-tools-0.2.0/src/lib.rs b/third_party/rust/byte-tools-0.2.0/src/lib.rs new file mode 100644 index 000000000000..323bf38f582e --- /dev/null +++ b/third_party/rust/byte-tools-0.2.0/src/lib.rs @@ -0,0 +1,37 @@ +#![no_std] +use core::ptr; + +mod read_single; +mod write_single; +mod read_slice; +mod write_slice; + +pub use read_single::*; +pub use write_single::*; +pub use read_slice::*; +pub use write_slice::*; + +/// Copy bytes from src to dest +#[inline] +pub fn copy_memory(src: &[u8], dst: &mut [u8]) { + assert!(dst.len() >= src.len()); + unsafe { + let srcp = src.as_ptr(); + let dstp = dst.as_mut_ptr(); + ptr::copy_nonoverlapping(srcp, dstp, src.len()); + } +} + +/// Zero all bytes in dst +#[inline] +pub fn zero(dst: &mut [u8]) { + set(dst, 0); +} + +/// Sets all bytes in `dst` equal to `value` +#[inline] +pub fn set(dst: &mut [u8], value: u8) { + unsafe { + ptr::write_bytes(dst.as_mut_ptr(), value, dst.len()); + } +} \ No newline at end of file diff --git a/third_party/rust/byte-tools/src/read_single.rs b/third_party/rust/byte-tools-0.2.0/src/read_single.rs similarity index 100% rename from third_party/rust/byte-tools/src/read_single.rs rename to third_party/rust/byte-tools-0.2.0/src/read_single.rs diff --git a/third_party/rust/byte-tools/src/read_slice.rs b/third_party/rust/byte-tools-0.2.0/src/read_slice.rs similarity index 100% rename from third_party/rust/byte-tools/src/read_slice.rs rename to third_party/rust/byte-tools-0.2.0/src/read_slice.rs diff --git a/third_party/rust/byte-tools/src/write_single.rs b/third_party/rust/byte-tools-0.2.0/src/write_single.rs similarity index 100% rename from third_party/rust/byte-tools/src/write_single.rs rename to third_party/rust/byte-tools-0.2.0/src/write_single.rs diff --git a/third_party/rust/byte-tools/src/write_slice.rs b/third_party/rust/byte-tools-0.2.0/src/write_slice.rs similarity index 100% rename from third_party/rust/byte-tools/src/write_slice.rs rename to third_party/rust/byte-tools-0.2.0/src/write_slice.rs diff --git a/third_party/rust/byte-tools/.cargo-checksum.json b/third_party/rust/byte-tools/.cargo-checksum.json index 0e07b2def735..397d09e85fe2 100644 --- a/third_party/rust/byte-tools/.cargo-checksum.json +++ b/third_party/rust/byte-tools/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"af6af6ea1dfa296af5dc58986d1afb46952328588069ec0b08723db439e9972d","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"52232c2cee3bb7d8cabe47ef367f1bf8bb607c22bdfca0219d6156cb7f446e9d","src/lib.rs":"9c96cffef7458fc7bd9e4e61270b69d539ff3a9225a0319b7996155c25ff96ab","src/read_single.rs":"3ab78b15754c2a7848a1be871ff6ee2a31a099f8f4f89be44ad210cda0dbcc9a","src/read_slice.rs":"b3790f2fd080db97e239c05c63da123ea375fb9b354dc9cacb859ed9c44f552e","src/write_single.rs":"1cee4f2f5d8690e47840ea7017539ead417a26abc0717137442a6d9d2875afe4","src/write_slice.rs":"de90e6b9cfca67125871bee7cef55c63574b1871a6584e51fc00a97e5877fe69"},"package":"560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"} \ No newline at end of file +{"files":{"Cargo.toml":"365cb0aa728934d2d9be1c45f2e135c1dc4b2305b20c7f34210c0ab11cadc21c","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"52232c2cee3bb7d8cabe47ef367f1bf8bb607c22bdfca0219d6156cb7f446e9d","src/lib.rs":"c8fb45d44cae0b1094bf8cef5059827b28b490eb14a3865fa536b61241c2c8c4"},"package":"980479e6fde23246dfb54d47580d66b4e99202e7579c5eaa9fe10ecb5ebd2182"} \ No newline at end of file diff --git a/third_party/rust/byte-tools/Cargo.toml b/third_party/rust/byte-tools/Cargo.toml index 32bf0cedc2be..09f73d955d07 100644 --- a/third_party/rust/byte-tools/Cargo.toml +++ b/third_party/rust/byte-tools/Cargo.toml @@ -12,9 +12,9 @@ [package] name = "byte-tools" -version = "0.2.0" -authors = ["The Rust-Crypto Project Developers"] -description = "Utility functions for working with bytes" +version = "0.3.0" +authors = ["RustCrypto Developers"] +description = "Bytes related utility functions" documentation = "https://docs.rs/byte-tools" keywords = ["bytes"] license = "MIT/Apache-2.0" diff --git a/third_party/rust/byte-tools/src/lib.rs b/third_party/rust/byte-tools/src/lib.rs index 323bf38f582e..b4a450f9fbde 100644 --- a/third_party/rust/byte-tools/src/lib.rs +++ b/third_party/rust/byte-tools/src/lib.rs @@ -1,37 +1,29 @@ #![no_std] use core::ptr; -mod read_single; -mod write_single; -mod read_slice; -mod write_slice; - -pub use read_single::*; -pub use write_single::*; -pub use read_slice::*; -pub use write_slice::*; - -/// Copy bytes from src to dest -#[inline] -pub fn copy_memory(src: &[u8], dst: &mut [u8]) { +/// Copy bytes from `src` to `dst` +/// +/// Panics if `src.len() < dst.len()` +#[inline(always)] +pub fn copy(src: &[u8], dst: &mut [u8]) { assert!(dst.len() >= src.len()); unsafe { - let srcp = src.as_ptr(); - let dstp = dst.as_mut_ptr(); - ptr::copy_nonoverlapping(srcp, dstp, src.len()); + ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len()); } } -/// Zero all bytes in dst -#[inline] +/// Zero all bytes in `dst` +#[inline(always)] pub fn zero(dst: &mut [u8]) { - set(dst, 0); + unsafe { + ptr::write_bytes(dst.as_mut_ptr(), 0, dst.len()); + } } /// Sets all bytes in `dst` equal to `value` -#[inline] +#[inline(always)] pub fn set(dst: &mut [u8], value: u8) { unsafe { ptr::write_bytes(dst.as_mut_ptr(), value, dst.len()); } -} \ No newline at end of file +} diff --git a/third_party/rust/digest-0.7.6/.cargo-checksum.json b/third_party/rust/digest-0.7.6/.cargo-checksum.json new file mode 100644 index 000000000000..bcc3f10575a3 --- /dev/null +++ b/third_party/rust/digest-0.7.6/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"b3667b1e1a3985dd2c9e7873f6945c2d7163ed7da95569f40c2097285a325ec4","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/dev.rs":"c824f834fa8b8c729024e4ec61138e89c26a56bfb6b50295600dddb5ff8fff62","src/digest.rs":"6710ac33c80e6159a2396839794fc76a61b94ab573516a69486457b3e291c793","src/errors.rs":"cff5bf2350bc109ad4f08caacf6780ff1e7016d9995f0847e84e96a8e31ab9d5","src/lib.rs":"bf4e93ebd066513001f3d6d77024ae8addf4df4fd89f76549fd1b73df386f3e4"},"package":"03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"} \ No newline at end of file diff --git a/third_party/rust/digest-0.7.6/Cargo.toml b/third_party/rust/digest-0.7.6/Cargo.toml new file mode 100644 index 000000000000..d4202475759a --- /dev/null +++ b/third_party/rust/digest-0.7.6/Cargo.toml @@ -0,0 +1,32 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "digest" +version = "0.7.6" +authors = ["RustCrypto Developers"] +description = "Traits for cryptographic hash functions" +documentation = "https://docs.rs/digest" +keywords = ["digest", "crypto", "hash"] +categories = ["cryptography", "no-std"] +license = "MIT/Apache-2.0" +repository = "https://github.com/RustCrypto/traits" +[package.metadata.docs.rs] +features = ["std"] +[dependencies.generic-array] +version = "0.9" + +[features] +dev = [] +std = [] +[badges.travis-ci] +repository = "RustCrypto/traits" diff --git a/third_party/rust/digest-0.7.6/LICENSE-APACHE b/third_party/rust/digest-0.7.6/LICENSE-APACHE new file mode 100644 index 000000000000..78173fa2e753 --- /dev/null +++ b/third_party/rust/digest-0.7.6/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/digest-0.7.6/LICENSE-MIT b/third_party/rust/digest-0.7.6/LICENSE-MIT new file mode 100644 index 000000000000..8dcb85b30273 --- /dev/null +++ b/third_party/rust/digest-0.7.6/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2017 Artyom Pavlov + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/digest-0.7.6/src/dev.rs b/third_party/rust/digest-0.7.6/src/dev.rs new file mode 100644 index 000000000000..35778cd6e09f --- /dev/null +++ b/third_party/rust/digest-0.7.6/src/dev.rs @@ -0,0 +1,171 @@ +use super::{Digest, Input, VariableOutput, ExtendableOutput, XofReader}; +use core::fmt::Debug; + +pub struct Test { + pub name: &'static str, + pub input: &'static [u8], + pub output: &'static [u8], +} + +#[macro_export] +macro_rules! new_tests { + ( $( $name:expr ),* ) => { + [$( + Test { + name: $name, + input: include_bytes!(concat!("data/", $name, ".input.bin")), + output: include_bytes!(concat!("data/", $name, ".output.bin")), + }, + )*] + }; + ( $( $name:expr ),+, ) => (new_tests!($($name),+)) +} + +pub fn main_test(tests: &[Test]) { + // Test that it works when accepting the message all at once + for t in tests.iter() { + let mut sh = D::default(); + sh.input(t.input); + + let out = sh.result(); + + assert_eq!(out[..], t.output[..]); + } + + // Test that it works when accepting the message in pieces + for t in tests.iter() { + let mut sh = D::default(); + let len = t.input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + sh.input(&t.input[len - left..take + len - left]); + left = left - take; + } + + let out = sh.result(); + + assert_eq!(out[..], t.output[..]); + } +} + +pub fn variable_test(tests: &[Test]) + where D: Input + VariableOutput + Clone + Debug +{ + let mut buf = [0u8; 1024]; + // Test that it works when accepting the message all at once + for t in tests.iter() { + let mut sh = D::new(t.output.len()).unwrap(); + sh.process(t.input); + + let out = sh.variable_result(&mut buf[..t.output.len()]).unwrap(); + + assert_eq!(out[..], t.output[..]); + } + + // Test that it works when accepting the message in pieces + for t in tests.iter() { + let mut sh = D::new(t.output.len()).unwrap(); + let len = t.input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + sh.process(&t.input[len - left..take + len - left]); + left = left - take; + } + + let out = sh.variable_result(&mut buf[..t.output.len()]).unwrap(); + + assert_eq!(out[..], t.output[..]); + } +} + + +pub fn xof_test(tests: &[Test]) + where D: Input + ExtendableOutput + Default + Debug + Clone +{ + let mut buf = [0u8; 1024]; + // Test that it works when accepting the message all at once + for t in tests.iter() { + let mut sh = D::default(); + sh.process(t.input); + + let out = &mut buf[..t.output.len()]; + sh.xof_result().read(out); + + assert_eq!(out[..], t.output[..]); + } + + // Test that it works when accepting the message in pieces + for t in tests.iter() { + let mut sh = D::default(); + let len = t.input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + sh.process(&t.input[len - left..take + len - left]); + left = left - take; + } + + let out = &mut buf[..t.output.len()]; + sh.xof_result().read(out); + + assert_eq!(out[..], t.output[..]); + } + + // Test reeading from reader byte by byte + for t in tests.iter() { + let mut sh = D::default(); + sh.process(t.input); + + let mut reader = sh.xof_result(); + let out = &mut buf[..t.output.len()]; + for chunk in out.chunks_mut(1) { + reader.read(chunk); + } + + assert_eq!(out[..], t.output[..]); + } +} + +pub fn one_million_a(expected: &[u8]) { + let mut sh = D::default(); + for _ in 0..50000 { + sh.input(&[b'a'; 10]); + } + sh.input(&[b'a'; 500000]); + let out = sh.result(); + assert_eq!(out[..], expected[..]); +} + + +#[macro_export] +macro_rules! bench_digest { + ($name:ident, $engine:path, $bs:expr) => { + #[bench] + fn $name(b: &mut Bencher) { + let mut d = <$engine>::default(); + let data = [0; $bs]; + + b.iter(|| { + d.input(&data); + }); + + b.bytes = $bs; + } + }; + + ($engine:path) => { + extern crate test; + + use test::Bencher; + use digest::Digest; + + bench_digest!(bench1_16, $engine, 1<<4); + bench_digest!(bench2_64, $engine, 1<<6); + bench_digest!(bench3_256, $engine, 1<<8); + bench_digest!(bench4_1k, $engine, 1<<10); + bench_digest!(bench5_4k, $engine, 1<<12); + bench_digest!(bench6_16k, $engine, 1<<14); + } +} diff --git a/third_party/rust/digest-0.7.6/src/digest.rs b/third_party/rust/digest-0.7.6/src/digest.rs new file mode 100644 index 000000000000..ab4ad392645d --- /dev/null +++ b/third_party/rust/digest-0.7.6/src/digest.rs @@ -0,0 +1,86 @@ +use super::{Input, BlockInput, FixedOutput}; +use generic_array::GenericArray; +#[cfg(feature = "std")] +use std::io; + +type Output = GenericArray; + +/// The `Digest` trait specifies an interface common for digest functions. +/// +/// It's a convinience wrapper around `Input`, `FixedOutput`, `BlockInput` and +/// `Default` traits. It also provides additional convenience methods. +pub trait Digest: Input + BlockInput + FixedOutput + Default { + /// Create new hasher instance + fn new() -> Self { + Self::default() + } + + /// Digest input data. This method can be called repeatedly + /// for use with streaming messages. + fn input(&mut self, input: &[u8]) { + self.process(input); + } + + /// Retrieve the digest result. This method consumes digest instance. + fn result(self) -> Output { + self.fixed_result() + } + + /// Convenience function to compute hash of the `data`. It will handle + /// hasher creation, data feeding and finalization. + /// + /// Example: + /// + /// ```rust,ignore + /// println!("{:x}", sha2::Sha256::digest(b"Hello world")); + /// ``` + #[inline] + fn digest(data: &[u8]) -> Output { + let mut hasher = Self::default(); + hasher.process(data); + hasher.fixed_result() + } + + /// Convenience function to compute hash of the string. It's equivalent to + /// `digest(input_string.as_bytes())`. + #[inline] + fn digest_str(str: &str) -> Output { + Self::digest(str.as_bytes()) + } + + /// Convenience function which takes `std::io::Read` as a source and computes + /// value of digest function `D`, e.g. SHA-2, SHA-3, BLAKE2, etc. using 1 KB + /// blocks. + /// + /// Usage example: + /// + /// ```rust,ignore + /// use std::fs; + /// use sha2::{Sha256, Digest}; + /// + /// let mut file = fs::File::open("Cargo.toml")?; + /// let result = Sha256::digest_reader(&mut file)?; + /// println!("{:x}", result); + /// ``` + #[cfg(feature = "std")] + #[inline] + fn digest_reader(source: &mut io::Read) + -> io::Result> + { + let mut hasher = Self::default(); + + let mut buf = [0u8; 8 * 1024]; + + loop { + let len = match source.read(&mut buf) { + Ok(0) => return Ok(hasher.result()), + Ok(len) => len, + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, + Err(e) => Err(e)?, + }; + hasher.process(&buf[..len]); + } + } +} + +impl Digest for D {} diff --git a/third_party/rust/digest-0.7.6/src/errors.rs b/third_party/rust/digest-0.7.6/src/errors.rs new file mode 100644 index 000000000000..7182a31ae93a --- /dev/null +++ b/third_party/rust/digest-0.7.6/src/errors.rs @@ -0,0 +1,37 @@ +use core::fmt; +#[cfg(feature = "std")] +use std::error; + +/// The error type for variable hasher initialization +#[derive(Clone, Copy, Debug, Default)] +pub struct InvalidOutputSize; + +/// The error type for variable hasher result +#[derive(Clone, Copy, Debug, Default)] +pub struct InvalidBufferLength; + +impl fmt::Display for InvalidOutputSize { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("invalid output size") + } +} + +impl fmt::Display for InvalidBufferLength { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("invalid buffer length") + } +} + +#[cfg(feature = "std")] +impl error::Error for InvalidOutputSize { + fn description(&self) -> &str { + "invalid output size" + } +} + +#[cfg(feature = "std")] +impl error::Error for InvalidBufferLength { + fn description(&self) -> &str { + "invalid buffer size" + } +} diff --git a/third_party/rust/digest-0.7.6/src/lib.rs b/third_party/rust/digest-0.7.6/src/lib.rs new file mode 100644 index 000000000000..9806caa935a1 --- /dev/null +++ b/third_party/rust/digest-0.7.6/src/lib.rs @@ -0,0 +1,98 @@ +//! This crate provides traits for describing funcionality of cryptographic hash +//! functions. +//! +//! By default std functionality in this crate disabled. (e.g. method for +//! hashing `Read`ers) To enable it turn on `std` feature in your `Cargo.toml` +//! for this crate. +#![cfg_attr(not(feature = "std"), no_std)] +pub extern crate generic_array; + +#[cfg(feature = "std")] +use std as core; +use generic_array::{GenericArray, ArrayLength}; + +mod digest; +mod errors; +#[cfg(feature = "dev")] +pub mod dev; + +pub use errors::{InvalidOutputSize, InvalidBufferLength}; +pub use digest::Digest; + +// `process` is choosen to not overlap with `input` method in the digest trait +// change it on trait alias stabilization + +/// Trait for processing input data +pub trait Input { + /// Digest input data. This method can be called repeatedly + /// for use with streaming messages. + fn process(&mut self, input: &[u8]); +} + +/// Trait to indicate that digest function processes data in blocks of size +/// `BlockSize`. Main usage of this trait is for implementing HMAC generically. +pub trait BlockInput { + type BlockSize: ArrayLength; +} + +/// Trait for returning digest result with the fixed size +pub trait FixedOutput { + type OutputSize: ArrayLength; + + /// Retrieve the digest result. This method consumes digest instance. + fn fixed_result(self) -> GenericArray; +} + +/// The error type for variable digest output +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub struct InvalidLength; + +/// Trait for returning digest result with the varaible size +pub trait VariableOutput: core::marker::Sized { + /// Create new hasher instance with given output size. Will return + /// `Err(InvalidLength)` in case if hasher can not work with the given + /// output size. Will always return an error if output size equals to zero. + fn new(output_size: usize) -> Result; + + /// Get output size of the hasher instance provided to the `new` method + fn output_size(&self) -> usize; + + /// Retrieve the digest result into provided buffer. Length of the buffer + /// must be equal to output size provided to the `new` method, otherwise + /// `Err(InvalidLength)` will be returned + fn variable_result(self, buffer: &mut [u8]) -> Result<&[u8], InvalidLength>; +} + +/// Trait for decribing readers which are used to extract extendable output +/// from the resulting state of hash function. +pub trait XofReader { + /// Read output into the `buffer`. Can be called unlimited number of times. + fn read(&mut self, buffer: &mut [u8]); +} + +/// Trait which describes extendable output (XOF) of hash functions. Using this +/// trait you first need to get structure which implements `XofReader`, using +/// which you can read extendable output. +pub trait ExtendableOutput { + type Reader: XofReader; + + /// Finalize hash function and return XOF reader + fn xof_result(self) -> Self::Reader; +} + +/// Macro for defining opaque `Debug` implementation. It will use the following +/// format: "HasherName { ... }". While it's convinient to have it +/// (e.g. for including in other structs), it could be undesirable to leak +/// internall state, which can happen for example through uncareful logging. +#[macro_export] +macro_rules! impl_opaque_debug { + ($state:ty) => { + impl ::core::fmt::Debug for $state { + fn fmt(&self, f: &mut ::core::fmt::Formatter) + -> Result<(), ::core::fmt::Error> + { + write!(f, concat!(stringify!($state), " {{ ... }}")) + } + } + } +} diff --git a/third_party/rust/digest/.cargo-checksum.json b/third_party/rust/digest/.cargo-checksum.json index bcc3f10575a3..9429389396cf 100644 --- a/third_party/rust/digest/.cargo-checksum.json +++ b/third_party/rust/digest/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"b3667b1e1a3985dd2c9e7873f6945c2d7163ed7da95569f40c2097285a325ec4","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/dev.rs":"c824f834fa8b8c729024e4ec61138e89c26a56bfb6b50295600dddb5ff8fff62","src/digest.rs":"6710ac33c80e6159a2396839794fc76a61b94ab573516a69486457b3e291c793","src/errors.rs":"cff5bf2350bc109ad4f08caacf6780ff1e7016d9995f0847e84e96a8e31ab9d5","src/lib.rs":"bf4e93ebd066513001f3d6d77024ae8addf4df4fd89f76549fd1b73df386f3e4"},"package":"03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"} \ No newline at end of file +{"files":{"Cargo.toml":"fe0caba7c3959c31f8b7a53d6d077a074e399c7604a2b03dfddcce9c0e56a81e","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/dev.rs":"5890305be2cd3d221d1c2ce295b911cc57017dc341966ba434def4a072f8bf1c","src/digest.rs":"73f564cb8084e61baf850948443bacdea81727dfbff5abeb520c0e5bb690da7a","src/dyn_digest.rs":"2b3151c46d09dae2b7b0d0788d7bcc3517fe638c6a3f6fe43e357494de538049","src/errors.rs":"2584007e98d691160313cc27e6237db9bd886e9774137b59a1289a20054e9375","src/lib.rs":"8b336814939efcb1c1157ccadd52d9e4d6c99a84a799af2fe70cc50d05c45a32"},"package":"05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"} \ No newline at end of file diff --git a/third_party/rust/digest/Cargo.toml b/third_party/rust/digest/Cargo.toml index d4202475759a..5b336043fcf1 100644 --- a/third_party/rust/digest/Cargo.toml +++ b/third_party/rust/digest/Cargo.toml @@ -12,21 +12,25 @@ [package] name = "digest" -version = "0.7.6" +version = "0.8.0" authors = ["RustCrypto Developers"] description = "Traits for cryptographic hash functions" documentation = "https://docs.rs/digest" keywords = ["digest", "crypto", "hash"] categories = ["cryptography", "no-std"] -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" repository = "https://github.com/RustCrypto/traits" [package.metadata.docs.rs] features = ["std"] +[dependencies.blobby] +version = "0.1" +optional = true + [dependencies.generic-array] -version = "0.9" +version = "0.12" [features] -dev = [] +dev = ["blobby"] std = [] [badges.travis-ci] repository = "RustCrypto/traits" diff --git a/third_party/rust/digest/src/dev.rs b/third_party/rust/digest/src/dev.rs index 35778cd6e09f..e9950ee799bd 100644 --- a/third_party/rust/digest/src/dev.rs +++ b/third_party/rust/digest/src/dev.rs @@ -1,146 +1,195 @@ -use super::{Digest, Input, VariableOutput, ExtendableOutput, XofReader}; +use super::{Input, VariableOutput, ExtendableOutput, Reset, XofReader}; use core::fmt::Debug; -pub struct Test { - pub name: &'static str, - pub input: &'static [u8], - pub output: &'static [u8], -} - #[macro_export] -macro_rules! new_tests { - ( $( $name:expr ),* ) => { - [$( - Test { - name: $name, - input: include_bytes!(concat!("data/", $name, ".input.bin")), - output: include_bytes!(concat!("data/", $name, ".output.bin")), - }, - )*] - }; - ( $( $name:expr ),+, ) => (new_tests!($($name),+)) +macro_rules! new_test { + ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident) => { + #[test] + fn $name() { + use digest::blobby::Blob2Iterator; + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + + for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() { + let input = row[0]; + let output = row[1]; + if let Some(desc) = $test_func::<$hasher>(input, output) { + panic!("\n\ + Failed test №{}: {}\n\ + input:\t{:?}\n\ + output:\t{:?}\n", + i, desc, input, output, + ); + } + } + } + } } -pub fn main_test(tests: &[Test]) { - // Test that it works when accepting the message all at once - for t in tests.iter() { - let mut sh = D::default(); - sh.input(t.input); +// module to separate Digest from other traits +mod foo { + use super::super::Digest; + use core::fmt::Debug; - let out = sh.result(); + pub fn digest_test(input: &[u8], output: &[u8]) -> Option<&'static str> + where D: Digest + Debug + Clone + { + let mut hasher = D::new(); + // Test that it works when accepting the message all at once + hasher.input(input); + let mut hasher2 = hasher.clone(); + if hasher.result().as_slice() != output { + return Some("whole message"); + } - assert_eq!(out[..], t.output[..]); - } + // Test if reset works correctly + hasher2.reset(); + hasher2.input(input); + if hasher2.result().as_slice() != output { + return Some("whole message after reset"); + } - // Test that it works when accepting the message in pieces - for t in tests.iter() { - let mut sh = D::default(); - let len = t.input.len(); + // Test that it works when accepting the message in pieces + let mut hasher = D::new(); + let len = input.len(); let mut left = len; while left > 0 { let take = (left + 1) / 2; - sh.input(&t.input[len - left..take + len - left]); + hasher.input(&input[len - left..take + len - left]); left = left - take; } + if hasher.result().as_slice() != output { + return Some("message in pieces"); + } + // Test processing byte-by-byte + let mut hasher = D::new(); + for chunk in input.chunks(1) { + hasher.input(chunk) + } + if hasher.result().as_slice() != output { + return Some("message byte-by-byte"); + } + None + } + + + pub fn one_million_a(expected: &[u8]) + where D: Digest + Debug + Clone + { + let mut sh = D::new(); + for _ in 0..50_000 { + sh.input(&[b'a'; 10]); + } + sh.input(&[b'a'; 500_000][..]); let out = sh.result(); - - assert_eq!(out[..], t.output[..]); + assert_eq!(out[..], expected[..]); } } -pub fn variable_test(tests: &[Test]) - where D: Input + VariableOutput + Clone + Debug +pub use self::foo::{digest_test, one_million_a}; + +pub fn xof_test(input: &[u8], output: &[u8]) + -> Option<&'static str> + where D: Input + ExtendableOutput + Default + Debug + Reset + Clone { + let mut hasher = D::default(); let mut buf = [0u8; 1024]; // Test that it works when accepting the message all at once - for t in tests.iter() { - let mut sh = D::new(t.output.len()).unwrap(); - sh.process(t.input); + hasher.input(input); - let out = sh.variable_result(&mut buf[..t.output.len()]).unwrap(); + let mut hasher2 = hasher.clone(); + { + let out = &mut buf[..output.len()]; + hasher.xof_result().read(out); - assert_eq!(out[..], t.output[..]); + if out != output { return Some("whole message"); } } - // Test that it works when accepting the message in pieces - for t in tests.iter() { - let mut sh = D::new(t.output.len()).unwrap(); - let len = t.input.len(); - let mut left = len; - while left > 0 { - let take = (left + 1) / 2; - sh.process(&t.input[len - left..take + len - left]); - left = left - take; - } + // Test if hasher resets correctly + hasher2.reset(); + hasher2.input(input); - let out = sh.variable_result(&mut buf[..t.output.len()]).unwrap(); + { + let out = &mut buf[..output.len()]; + hasher2.xof_result().read(out); - assert_eq!(out[..], t.output[..]); + if out != output { return Some("whole message after reset"); } } + + // Test if hasher accepts message in pieces correctly + let mut hasher = D::default(); + let len = input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + hasher.input(&input[len - left..take + len - left]); + left = left - take; + } + + { + let out = &mut buf[..output.len()]; + hasher.xof_result().read(out); + if out != output { return Some("message in pieces"); } + } + + // Test reading from reader byte by byte + let mut hasher = D::default(); + hasher.input(input); + + let mut reader = hasher.xof_result(); + let out = &mut buf[..output.len()]; + for chunk in out.chunks_mut(1) { + reader.read(chunk); + } + + if out != output { return Some("message in pieces"); } + None } - -pub fn xof_test(tests: &[Test]) - where D: Input + ExtendableOutput + Default + Debug + Clone +pub fn variable_test(input: &[u8], output: &[u8]) + -> Option<&'static str> + where D: Input + VariableOutput + Reset + Debug + Clone { - let mut buf = [0u8; 1024]; + let mut hasher = D::new(output.len()).unwrap(); + let mut buf = [0u8; 128]; + let buf = &mut buf[..output.len()]; // Test that it works when accepting the message all at once - for t in tests.iter() { - let mut sh = D::default(); - sh.process(t.input); + hasher.input(input); + let mut hasher2 = hasher.clone(); + hasher.variable_result(|res| buf.copy_from_slice(res)); + if buf != output { return Some("whole message"); } - let out = &mut buf[..t.output.len()]; - sh.xof_result().read(out); - - assert_eq!(out[..], t.output[..]); - } + // Test if reset works correctly + hasher2.reset(); + hasher2.input(input); + hasher2.variable_result(|res| buf.copy_from_slice(res)); + if buf != output { return Some("whole message after reset"); } // Test that it works when accepting the message in pieces - for t in tests.iter() { - let mut sh = D::default(); - let len = t.input.len(); - let mut left = len; - while left > 0 { - let take = (left + 1) / 2; - sh.process(&t.input[len - left..take + len - left]); - left = left - take; - } - - let out = &mut buf[..t.output.len()]; - sh.xof_result().read(out); - - assert_eq!(out[..], t.output[..]); + let mut hasher = D::new(output.len()).unwrap(); + let len = input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + hasher.input(&input[len - left..take + len - left]); + left = left - take; } + hasher.variable_result(|res| buf.copy_from_slice(res)); + if buf != output { return Some("message in pieces"); } - // Test reeading from reader byte by byte - for t in tests.iter() { - let mut sh = D::default(); - sh.process(t.input); - - let mut reader = sh.xof_result(); - let out = &mut buf[..t.output.len()]; - for chunk in out.chunks_mut(1) { - reader.read(chunk); - } - - assert_eq!(out[..], t.output[..]); + // Test processing byte-by-byte + let mut hasher = D::new(output.len()).unwrap(); + for chunk in input.chunks(1) { + hasher.input(chunk) } -} - -pub fn one_million_a(expected: &[u8]) { - let mut sh = D::default(); - for _ in 0..50000 { - sh.input(&[b'a'; 10]); - } - sh.input(&[b'a'; 500000]); - let out = sh.result(); - assert_eq!(out[..], expected[..]); + hasher.variable_result(|res| buf.copy_from_slice(res)); + if buf != output { return Some("message byte-by-byte"); } + None } #[macro_export] -macro_rules! bench_digest { +macro_rules! bench { ($name:ident, $engine:path, $bs:expr) => { #[bench] fn $name(b: &mut Bencher) { @@ -148,7 +197,7 @@ macro_rules! bench_digest { let data = [0; $bs]; b.iter(|| { - d.input(&data); + d.input(&data[..]); }); b.bytes = $bs; @@ -161,11 +210,9 @@ macro_rules! bench_digest { use test::Bencher; use digest::Digest; - bench_digest!(bench1_16, $engine, 1<<4); - bench_digest!(bench2_64, $engine, 1<<6); - bench_digest!(bench3_256, $engine, 1<<8); - bench_digest!(bench4_1k, $engine, 1<<10); - bench_digest!(bench5_4k, $engine, 1<<12); - bench_digest!(bench6_16k, $engine, 1<<14); + bench!(bench1_10, $engine, 10); + bench!(bench2_100, $engine, 100); + bench!(bench3_1000, $engine, 1000); + bench!(bench4_10000, $engine, 10000); } } diff --git a/third_party/rust/digest/src/digest.rs b/third_party/rust/digest/src/digest.rs index ab4ad392645d..50128e13ecef 100644 --- a/third_party/rust/digest/src/digest.rs +++ b/third_party/rust/digest/src/digest.rs @@ -1,30 +1,38 @@ -use super::{Input, BlockInput, FixedOutput}; -use generic_array::GenericArray; -#[cfg(feature = "std")] -use std::io; - -type Output = GenericArray; +use super::{Input, FixedOutput, Reset}; +use generic_array::{GenericArray, ArrayLength}; +use generic_array::typenum::Unsigned; /// The `Digest` trait specifies an interface common for digest functions. /// -/// It's a convinience wrapper around `Input`, `FixedOutput`, `BlockInput` and -/// `Default` traits. It also provides additional convenience methods. -pub trait Digest: Input + BlockInput + FixedOutput + Default { +/// It's a convenience wrapper around `Input`, `FixedOutput`, `Reset`, `Clone`, +/// and `Default` traits. It also provides additional convenience methods. +pub trait Digest { + type OutputSize: ArrayLength; /// Create new hasher instance - fn new() -> Self { - Self::default() - } + fn new() -> Self; - /// Digest input data. This method can be called repeatedly - /// for use with streaming messages. - fn input(&mut self, input: &[u8]) { - self.process(input); - } + /// Digest input data. + /// + /// This method can be called repeatedly for use with streaming messages. + fn input>(&mut self, data: B); - /// Retrieve the digest result. This method consumes digest instance. - fn result(self) -> Output { - self.fixed_result() - } + /// Digest input data in a chained manner. + fn chain>(self, data: B) -> Self where Self: Sized; + + /// Retrieve result and consume hasher instance. + fn result(self) -> GenericArray; + + /// Retrieve result and reset hasher instance. + /// + /// This method sometimes can be more efficient compared to hasher + /// re-creation. + fn result_reset(&mut self) -> GenericArray; + + /// Reset hasher instance to its initial state. + fn reset(&mut self); + + /// Get output size of the hasher + fn output_size() -> usize; /// Convenience function to compute hash of the `data`. It will handle /// hasher creation, data feeding and finalization. @@ -34,53 +42,45 @@ pub trait Digest: Input + BlockInput + FixedOutput + Default { /// ```rust,ignore /// println!("{:x}", sha2::Sha256::digest(b"Hello world")); /// ``` - #[inline] - fn digest(data: &[u8]) -> Output { - let mut hasher = Self::default(); - hasher.process(data); - hasher.fixed_result() - } - - /// Convenience function to compute hash of the string. It's equivalent to - /// `digest(input_string.as_bytes())`. - #[inline] - fn digest_str(str: &str) -> Output { - Self::digest(str.as_bytes()) - } - - /// Convenience function which takes `std::io::Read` as a source and computes - /// value of digest function `D`, e.g. SHA-2, SHA-3, BLAKE2, etc. using 1 KB - /// blocks. - /// - /// Usage example: - /// - /// ```rust,ignore - /// use std::fs; - /// use sha2::{Sha256, Digest}; - /// - /// let mut file = fs::File::open("Cargo.toml")?; - /// let result = Sha256::digest_reader(&mut file)?; - /// println!("{:x}", result); - /// ``` - #[cfg(feature = "std")] - #[inline] - fn digest_reader(source: &mut io::Read) - -> io::Result> - { - let mut hasher = Self::default(); - - let mut buf = [0u8; 8 * 1024]; - - loop { - let len = match source.read(&mut buf) { - Ok(0) => return Ok(hasher.result()), - Ok(len) => len, - Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, - Err(e) => Err(e)?, - }; - hasher.process(&buf[..len]); - } - } + fn digest(data: &[u8]) -> GenericArray; } -impl Digest for D {} +impl Digest for D { + type OutputSize = ::OutputSize; + + fn new() -> Self { + Self::default() + } + + fn input>(&mut self, data: B) { + Input::input(self, data); + } + + fn chain>(self, data: B) -> Self where Self: Sized { + Input::chain(self, data) + } + + fn result(self) -> GenericArray { + self.fixed_result() + } + + fn result_reset(&mut self) -> GenericArray { + let res = self.clone().fixed_result(); + self.reset(); + res + } + + fn reset(&mut self) { + ::reset(self) + } + + fn output_size() -> usize { + Self::OutputSize::to_usize() + } + + fn digest(data: &[u8]) -> GenericArray { + let mut hasher = Self::default(); + Input::input(&mut hasher, data); + hasher.fixed_result() + } +} diff --git a/third_party/rust/digest/src/dyn_digest.rs b/third_party/rust/digest/src/dyn_digest.rs new file mode 100644 index 000000000000..789cdc86ef06 --- /dev/null +++ b/third_party/rust/digest/src/dyn_digest.rs @@ -0,0 +1,56 @@ +#![cfg(feature = "std")] +use std::boxed::Box; + +use super::{Input, FixedOutput, Reset}; +use generic_array::typenum::Unsigned; + +/// The `DynDigest` trait is a modification of `Digest` trait suitable +/// for trait objects. +pub trait DynDigest { + /// Digest input data. + /// + /// This method can be called repeatedly for use with streaming messages. + fn input(&mut self, data: &[u8]); + + /// Retrieve result and reset hasher instance + fn result_reset(&mut self) -> Box<[u8]>; + + /// Retrieve result and consume boxed hasher instance + fn result(self: Box) -> Box<[u8]>; + + /// Reset hasher instance to its initial state. + fn reset(&mut self); + + /// Get output size of the hasher + fn output_size(&self) -> usize; +} + +impl DynDigest for D { + /// Digest input data. + /// + /// This method can be called repeatedly for use with streaming messages. + fn input(&mut self, data: &[u8]) { + Input::input(self, data); + } + + /// Retrieve result and reset hasher instance + fn result_reset(&mut self) -> Box<[u8]> { + let res = self.clone().fixed_result().to_vec().into_boxed_slice(); + Reset::reset(self); + res + } + + /// Retrieve result and consume boxed hasher instance + fn result(self: Box) -> Box<[u8]> { + self.fixed_result().to_vec().into_boxed_slice() + } + + fn reset(&mut self) { + Reset::reset(self); + } + + /// Get output size of the hasher + fn output_size(&self) -> usize { + ::OutputSize::to_usize() + } +} diff --git a/third_party/rust/digest/src/errors.rs b/third_party/rust/digest/src/errors.rs index 7182a31ae93a..aa026a21a1d0 100644 --- a/third_party/rust/digest/src/errors.rs +++ b/third_party/rust/digest/src/errors.rs @@ -6,32 +6,15 @@ use std::error; #[derive(Clone, Copy, Debug, Default)] pub struct InvalidOutputSize; -/// The error type for variable hasher result -#[derive(Clone, Copy, Debug, Default)] -pub struct InvalidBufferLength; - impl fmt::Display for InvalidOutputSize { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("invalid output size") } } -impl fmt::Display for InvalidBufferLength { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("invalid buffer length") - } -} - #[cfg(feature = "std")] impl error::Error for InvalidOutputSize { fn description(&self) -> &str { "invalid output size" } } - -#[cfg(feature = "std")] -impl error::Error for InvalidBufferLength { - fn description(&self) -> &str { - "invalid buffer size" - } -} diff --git a/third_party/rust/digest/src/lib.rs b/third_party/rust/digest/src/lib.rs index 9806caa935a1..1a364f808c2e 100644 --- a/third_party/rust/digest/src/lib.rs +++ b/third_party/rust/digest/src/lib.rs @@ -1,36 +1,59 @@ -//! This crate provides traits for describing funcionality of cryptographic hash +//! This crate provides traits which describe funcionality of cryptographic hash //! functions. //! -//! By default std functionality in this crate disabled. (e.g. method for -//! hashing `Read`ers) To enable it turn on `std` feature in your `Cargo.toml` -//! for this crate. -#![cfg_attr(not(feature = "std"), no_std)] +//! Traits in this repository can be separatedin two levels: +//! - Low level traits: `Input`, `BlockInput`, `Reset`, `FixedOutput`, +//! `VariableOutput`, `ExtendableOutput`. These traits atomically describe +//! available functionality of hash function implementations. +//! - Convinience trait: `Digest`, `DynDigest`. They are wrappers around +//! low level traits for most common hash-function use-cases. +//! +//! Additionally hash functions implement traits from `std`: `Default`, `Clone`, +//! `Write`. (the latter depends on enabled-by-default `std` crate feature) +//! +//! The `Digest` trait is the most commonly used trait. +#![no_std] +#![doc(html_logo_url = + "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] pub extern crate generic_array; - #[cfg(feature = "std")] -use std as core; +#[macro_use] extern crate std; +#[cfg(feature = "dev")] +pub extern crate blobby; use generic_array::{GenericArray, ArrayLength}; +#[cfg(feature = "std")] +use std::vec::Vec; mod digest; +mod dyn_digest; mod errors; #[cfg(feature = "dev")] pub mod dev; -pub use errors::{InvalidOutputSize, InvalidBufferLength}; +pub use errors::InvalidOutputSize; pub use digest::Digest; - -// `process` is choosen to not overlap with `input` method in the digest trait -// change it on trait alias stabilization +#[cfg(feature = "std")] +pub use dyn_digest::DynDigest; /// Trait for processing input data pub trait Input { - /// Digest input data. This method can be called repeatedly - /// for use with streaming messages. - fn process(&mut self, input: &[u8]); + /// Digest input data. + /// + /// This method can be called repeatedly, e.g. for processing streaming + /// messages. + fn input>(&mut self, data: B); + + /// Digest input data in a chained manner. + fn chain>(mut self, data: B) -> Self where Self: Sized { + self.input(data); + self + } } /// Trait to indicate that digest function processes data in blocks of size -/// `BlockSize`. Main usage of this trait is for implementing HMAC generically. +/// `BlockSize`. +/// +/// The main usage of this trait is for implementing HMAC generically. pub trait BlockInput { type BlockSize: ArrayLength; } @@ -39,59 +62,79 @@ pub trait BlockInput { pub trait FixedOutput { type OutputSize: ArrayLength; - /// Retrieve the digest result. This method consumes digest instance. + /// Retrieve result and consume hasher instance. fn fixed_result(self) -> GenericArray; } -/// The error type for variable digest output -#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct InvalidLength; - /// Trait for returning digest result with the varaible size pub trait VariableOutput: core::marker::Sized { - /// Create new hasher instance with given output size. Will return - /// `Err(InvalidLength)` in case if hasher can not work with the given - /// output size. Will always return an error if output size equals to zero. - fn new(output_size: usize) -> Result; + /// Create new hasher instance with the given output size. + /// + /// It will return `Err(InvalidOutputSize)` in case if hasher can not return + /// specified output size. It will always return an error if output size + /// equals to zero. + fn new(output_size: usize) -> Result; /// Get output size of the hasher instance provided to the `new` method fn output_size(&self) -> usize; - /// Retrieve the digest result into provided buffer. Length of the buffer - /// must be equal to output size provided to the `new` method, otherwise - /// `Err(InvalidLength)` will be returned - fn variable_result(self, buffer: &mut [u8]) -> Result<&[u8], InvalidLength>; + /// Retrieve result via closure and consume hasher. + /// + /// Closure is guaranteed to be called, length of the buffer passed to it + /// will be equal to `output_size`. + fn variable_result(self, f: F); + + /// Retrieve result into vector and consume hasher. + #[cfg(feature = "std")] + fn vec_result(self) -> Vec { + let mut buf = Vec::with_capacity(self.output_size()); + self.variable_result(|res| buf.extend_from_slice(res)); + buf + } } /// Trait for decribing readers which are used to extract extendable output -/// from the resulting state of hash function. +/// from XOF (extendable-output function) result. pub trait XofReader { /// Read output into the `buffer`. Can be called unlimited number of times. fn read(&mut self, buffer: &mut [u8]); } -/// Trait which describes extendable output (XOF) of hash functions. Using this -/// trait you first need to get structure which implements `XofReader`, using -/// which you can read extendable output. -pub trait ExtendableOutput { +/// Trait which describes extendable-output functions (XOF). +pub trait ExtendableOutput: core::marker::Sized { type Reader: XofReader; - /// Finalize hash function and return XOF reader + /// Retrieve XOF reader and consume hasher instance. fn xof_result(self) -> Self::Reader; + + /// Retrieve result into vector of specified length. + #[cfg(feature = "std")] + fn vec_result(self, n: usize) -> Vec { + let mut buf = vec![0u8; n]; + self.xof_result().read(&mut buf); + buf + } +} + +/// Trait for resetting hash instances +pub trait Reset { + /// Reset hasher instance to its initial state and return current state. + fn reset(&mut self); } -/// Macro for defining opaque `Debug` implementation. It will use the following -/// format: "HasherName { ... }". While it's convinient to have it -/// (e.g. for including in other structs), it could be undesirable to leak -/// internall state, which can happen for example through uncareful logging. #[macro_export] -macro_rules! impl_opaque_debug { - ($state:ty) => { - impl ::core::fmt::Debug for $state { - fn fmt(&self, f: &mut ::core::fmt::Formatter) - -> Result<(), ::core::fmt::Error> - { - write!(f, concat!(stringify!($state), " {{ ... }}")) +/// Implements `std::io::Write` trait for implementator of `Input` +macro_rules! impl_write { + ($hasher:ident) => { + #[cfg(feature = "std")] + impl ::std::io::Write for $hasher { + fn write(&mut self, buf: &[u8]) -> ::std::io::Result { + Input::input(self, buf); + Ok(buf.len()) + } + + fn flush(&mut self) -> ::std::io::Result<()> { + Ok(()) } } } diff --git a/third_party/rust/generic-array-0.9.0/.cargo-checksum.json b/third_party/rust/generic-array-0.9.0/.cargo-checksum.json new file mode 100644 index 000000000000..6616b505b573 --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"87ff65d640c137c26d338f96e21e769af1e1b2e7fa615b40a1bcc755448bb118","LICENSE":"ad4fcfaf8d5b12b97409c137a03d4a4e4b21024c65c54f976cc3b609c1bd5b0f","README.md":"9a1a45416eac57050036b13df6ec84d21d555e820726af3c782896bd9d37d94b","rustfmt.toml":"2a298b4ce1fe6e16b8f281a0035567b8eb15042ed3062729fd28224f29c2f75a","src/arr.rs":"cc1ea0a9ef6a524b90767cc8a89f6b939394a2948a645ed313c0bf5ce5a258a4","src/hex.rs":"bfbf304fb4dea6f7edc0569b38bf2ac7657ce089c5761891321722509e3b5076","src/impl_serde.rs":"805885478728b3c205b842d46deb377b7dd6dd4c4c50254064431f49f0981a2a","src/impls.rs":"8c54e294a82a2bf344bdcb9949b8a84903fb65698d6b1b1e0ab9f5e7847be64f","src/iter.rs":"e52217f04d0dc046f13ef2e3539b90eabd4d55bb85cf40f76ba0bf86d5e55ef0","src/lib.rs":"da93fa505eee94b40fce0fe98e26ed3bb4d2bc4d4869af01598b6e54fc9c0f8d","tests/hex.rs":"e909bc0564e7d52c5fcf172dfc0fac7085010c6a21d38581bf73a54ab2e256e1","tests/import_name.rs":"1235729ecbde47fc9a38b3bf35c750a53ed55e3cf967c9d2b24fd759dc9e9e0c","tests/mod.rs":"f4100c5338906c038636f98f4d2b3d272f59580662afa89d915eafb96d7bbcf9"},"package":"ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"} \ No newline at end of file diff --git a/third_party/rust/generic-array-0.9.0/Cargo.toml b/third_party/rust/generic-array-0.9.0/Cargo.toml new file mode 100644 index 000000000000..07c6064694ee --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/Cargo.toml @@ -0,0 +1,32 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "generic-array" +version = "0.9.0" +authors = ["Bartłomiej Kamiński "] +description = "Generic types implementing functionality of arrays" +documentation = "http://fizyk20.github.io/generic-array/generic_array/" +license = "MIT" +repository = "https://github.com/fizyk20/generic-array.git" + +[lib] +name = "generic_array" +[dependencies.typenum] +version = "1.9" + +[dependencies.serde] +version = "1.0" +optional = true +default-features = false +[dev-dependencies.serde_json] +version = "1.0" diff --git a/third_party/rust/generic-array-0.9.0/LICENSE b/third_party/rust/generic-array-0.9.0/LICENSE new file mode 100644 index 000000000000..5968bccccf99 --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bartłomiej Kamiński + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/third_party/rust/generic-array-0.9.0/README.md b/third_party/rust/generic-array-0.9.0/README.md new file mode 100644 index 000000000000..0864ed62736a --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/README.md @@ -0,0 +1,34 @@ +[![Crates.io](https://img.shields.io/crates/v/generic-array.svg)](https://crates.io/crates/generic-array) +[![Build Status](https://travis-ci.org/fizyk20/generic-array.svg?branch=master)](https://travis-ci.org/fizyk20/generic-array) +# generic-array + +This crate implements generic array types for Rust. + +[Documentation](http://fizyk20.github.io/generic-array/generic_array/) + +## Usage + +The Rust arrays `[T; N]` are problematic in that they can't be used generically with respect to `N`, so for example this won't work: + +```rust +struct Foo { + data: [i32; N] +} +``` + +**generic-array** defines a new trait `ArrayLength` and a struct `GenericArray>`, which let the above be implemented as: + +```rust +struct Foo> { + data: GenericArray +} +``` + +To actually define a type implementing `ArrayLength`, you can use unsigned integer types defined in [typenum](https://github.com/paholg/typenum) crate - for example, `GenericArray` would work almost like `[T; 5]` :) + +In version 0.1.1 an `arr!` macro was introduced, allowing for creation of arrays as shown below: + +```rust +let array = arr![u32; 1, 2, 3]; +assert_eq!(array[2], 3); +``` diff --git a/third_party/rust/generic-array-0.9.0/rustfmt.toml b/third_party/rust/generic-array-0.9.0/rustfmt.toml new file mode 100644 index 000000000000..3dc0db27b317 --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/rustfmt.toml @@ -0,0 +1,3 @@ +reorder_imports = true +reorder_imported_names = true +use_try_shorthand = true diff --git a/third_party/rust/generic-array-0.9.0/src/arr.rs b/third_party/rust/generic-array-0.9.0/src/arr.rs new file mode 100644 index 000000000000..51d87f63ca7e --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/src/arr.rs @@ -0,0 +1,57 @@ +//! Implementation for `arr!` macro. + +use super::ArrayLength; +use core::ops::Add; +use typenum::U1; + +/// Helper trait for `arr!` macro +pub trait AddLength>: ArrayLength { + /// Resulting length + type Output: ArrayLength; +} + +impl AddLength for N1 +where + N1: ArrayLength + Add, + N2: ArrayLength, + >::Output: ArrayLength, +{ + type Output = >::Output; +} + +/// Helper type for `arr!` macro +pub type Inc = >::Output; + +#[doc(hidden)] +#[macro_export] +macro_rules! arr_impl { + ($T:ty; $N:ty, [$($x:expr),*], []) => ({ + unsafe { $crate::transmute::<_, $crate::GenericArray<$T, $N>>([$($x),*]) } + }); + ($T:ty; $N:ty, [], [$x1:expr]) => ( + arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], []) + ); + ($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => ( + arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [$($x),*]) + ); + ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => ( + arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),*, $x1 as $T], []) + ); + ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => ( + arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),*, $x1 as $T], [$($x),*]) + ); +} + +/// Macro allowing for easy generation of Generic Arrays. +/// Example: `let test = arr![u32; 1, 2, 3];` +#[macro_export] +macro_rules! arr { + ($T:ty;) => ({ + unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) } + }); + ($T:ty; $($x:expr),*) => ( + arr_impl!($T; $crate::typenum::U0, [], [$($x),*]) + ); + ($($x:expr,)+) => (arr![$($x),*]); + () => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`") +} diff --git a/third_party/rust/generic-array-0.9.0/src/hex.rs b/third_party/rust/generic-array-0.9.0/src/hex.rs new file mode 100644 index 000000000000..1ce5332f781e --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/src/hex.rs @@ -0,0 +1,101 @@ +//! Generic array are commonly used as a return value for hash digests, so +//! it's a good idea to allow to hexlify them easily. This module implements +//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits. +//! +//! Example: +//! +//! ```rust +//! # #[macro_use] +//! # extern crate generic_array; +//! # extern crate typenum; +//! # fn main() { +//! let array = arr![u8; 10, 20, 30]; +//! assert_eq!(format!("{:x}", array), "0a141e"); +//! # } +//! ``` +//! + +use {ArrayLength, GenericArray}; +use core::fmt; +use core::ops::Add; +use core::str; +use typenum::*; + +static LOWER_CHARS: &'static [u8] = b"0123456789abcdef"; +static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF"; + +impl> fmt::LowerHex for GenericArray +where + T: Add, + >::Output: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let max_digits = f.precision().unwrap_or_else(|| self.len()); + + if T::to_usize() < 1024 { + // For small arrays use a stack allocated + // buffer of 2x number of bytes + let mut res = GenericArray::>::default(); + + for (i, c) in self.iter().take(max_digits).enumerate() { + res[i * 2] = LOWER_CHARS[(c >> 4) as usize]; + res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize]; + } + f.write_str( + unsafe { str::from_utf8_unchecked(&res[..max_digits * 2]) }, + )?; + } else { + // For large array use chunks of up to 1024 bytes (2048 hex chars) + let mut buf = [0u8; 2048]; + + for chunk in self[..max_digits].chunks(1024) { + for (i, c) in chunk.iter().enumerate() { + buf[i * 2] = LOWER_CHARS[(c >> 4) as usize]; + buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize]; + } + f.write_str(unsafe { + str::from_utf8_unchecked(&buf[..chunk.len() * 2]) + })?; + } + } + Ok(()) + } +} + +impl> fmt::UpperHex for GenericArray +where + T: Add, + >::Output: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let max_digits = f.precision().unwrap_or_else(|| self.len()); + + if T::to_usize() < 1024 { + // For small arrays use a stack allocated + // buffer of 2x number of bytes + let mut res = GenericArray::>::default(); + + for (i, c) in self.iter().take(max_digits).enumerate() { + res[i * 2] = UPPER_CHARS[(c >> 4) as usize]; + res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize]; + } + f.write_str( + unsafe { str::from_utf8_unchecked(&res[..max_digits * 2]) }, + )?; + } else { + // For large array use chunks of up to 1024 bytes (2048 hex chars) + let mut buf = [0u8; 2048]; + + for chunk in self[..max_digits].chunks(1024) { + for (i, c) in chunk.iter().enumerate() { + buf[i * 2] = UPPER_CHARS[(c >> 4) as usize]; + buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize]; + } + f.write_str(unsafe { + str::from_utf8_unchecked(&buf[..chunk.len() * 2]) + })?; + } + } + Ok(()) + } +} diff --git a/third_party/rust/generic-array-0.9.0/src/impl_serde.rs b/third_party/rust/generic-array-0.9.0/src/impl_serde.rs new file mode 100644 index 000000000000..fd7f4908053b --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/src/impl_serde.rs @@ -0,0 +1,68 @@ +//! Serde serialization/deserialization implementation + +use {ArrayLength, GenericArray}; +use core::fmt; +use core::marker::PhantomData; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::de::{self, SeqAccess, Visitor}; + +impl Serialize for GenericArray +where + T: Serialize, + N: ArrayLength, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.collect_seq(self.iter()) + } +} + +struct GAVisitor { + _t: PhantomData, + _n: PhantomData, +} + +impl<'de, T, N> Visitor<'de> for GAVisitor +where + T: Deserialize<'de> + Default, + N: ArrayLength, +{ + type Value = GenericArray; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("struct GenericArray") + } + + fn visit_seq(self, mut seq: A) -> Result, A::Error> + where + A: SeqAccess<'de>, + { + let mut result = GenericArray::default(); + for i in 0..N::to_usize() { + result[i] = seq.next_element()?.ok_or_else( + || de::Error::invalid_length(i, &self), + )?; + } + Ok(result) + } +} + +impl<'de, T, N> Deserialize<'de> for GenericArray +where + T: Deserialize<'de> + Default, + N: ArrayLength, +{ + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let visitor = GAVisitor { + _t: PhantomData, + _n: PhantomData, + }; + deserializer.deserialize_seq(visitor) + } +} diff --git a/third_party/rust/generic-array-0.9.0/src/impls.rs b/third_party/rust/generic-array-0.9.0/src/impls.rs new file mode 100644 index 000000000000..3055876661a6 --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/src/impls.rs @@ -0,0 +1,171 @@ +use super::{ArrayLength, GenericArray}; +use core::borrow::{Borrow, BorrowMut}; +use core::cmp::Ordering; +use core::fmt::{self, Debug}; +use core::hash::{Hash, Hasher}; + +impl Default for GenericArray +where + N: ArrayLength, +{ + #[inline] + fn default() -> Self { + Self::generate(|_| T::default()) + } +} + +impl Clone for GenericArray +where + N: ArrayLength, +{ + fn clone(&self) -> GenericArray { + self.map_ref(|x| x.clone()) + } +} + +impl Copy for GenericArray +where + N: ArrayLength, + N::ArrayType: Copy, +{ +} + +impl PartialEq for GenericArray +where + N: ArrayLength, +{ + fn eq(&self, other: &Self) -> bool { + **self == **other + } +} +impl Eq for GenericArray +where + N: ArrayLength, +{ +} + +impl PartialOrd for GenericArray +where + N: ArrayLength, +{ + fn partial_cmp(&self, other: &GenericArray) -> Option { + PartialOrd::partial_cmp(self.as_slice(), other.as_slice()) + } +} + +impl Ord for GenericArray +where + N: ArrayLength, +{ + fn cmp(&self, other: &GenericArray) -> Ordering { + Ord::cmp(self.as_slice(), other.as_slice()) + } +} + +impl Debug for GenericArray +where + N: ArrayLength, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self[..].fmt(fmt) + } +} + +impl Borrow<[T]> for GenericArray +where + N: ArrayLength, +{ + fn borrow(&self) -> &[T] { + &self[..] + } +} + +impl BorrowMut<[T]> for GenericArray +where + N: ArrayLength, +{ + fn borrow_mut(&mut self) -> &mut [T] { + &mut self[..] + } +} + +impl AsRef<[T]> for GenericArray +where + N: ArrayLength, +{ + fn as_ref(&self) -> &[T] { + &self[..] + } +} + +impl AsMut<[T]> for GenericArray +where + N: ArrayLength, +{ + fn as_mut(&mut self) -> &mut [T] { + &mut self[..] + } +} + +impl Hash for GenericArray +where + N: ArrayLength, +{ + fn hash(&self, state: &mut H) + where + H: Hasher, + { + Hash::hash(&self[..], state) + } +} + +macro_rules! impl_from { + ($($n: expr => $ty: ty),*) => { + $( + impl From<[T; $n]> for GenericArray { + fn from(arr: [T; $n]) -> Self { + use core::mem::{forget, transmute_copy}; + let x = unsafe { transmute_copy(&arr) }; + forget(arr); + x + } + } + )* + + } +} + +impl_from! { + 1 => ::typenum::U1, + 2 => ::typenum::U2, + 3 => ::typenum::U3, + 4 => ::typenum::U4, + 5 => ::typenum::U5, + 6 => ::typenum::U6, + 7 => ::typenum::U7, + 8 => ::typenum::U8, + 9 => ::typenum::U9, + 10 => ::typenum::U10, + 11 => ::typenum::U11, + 12 => ::typenum::U12, + 13 => ::typenum::U13, + 14 => ::typenum::U14, + 15 => ::typenum::U15, + 16 => ::typenum::U16, + 17 => ::typenum::U17, + 18 => ::typenum::U18, + 19 => ::typenum::U19, + 20 => ::typenum::U20, + 21 => ::typenum::U21, + 22 => ::typenum::U22, + 23 => ::typenum::U23, + 24 => ::typenum::U24, + 25 => ::typenum::U25, + 26 => ::typenum::U26, + 27 => ::typenum::U27, + 28 => ::typenum::U28, + 29 => ::typenum::U29, + 30 => ::typenum::U30, + 31 => ::typenum::U31, + 32 => ::typenum::U32 +} \ No newline at end of file diff --git a/third_party/rust/generic-array-0.9.0/src/iter.rs b/third_party/rust/generic-array-0.9.0/src/iter.rs new file mode 100644 index 000000000000..b9282761a45f --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/src/iter.rs @@ -0,0 +1,117 @@ +//! `GenericArray` iterator implementation. + +use super::{ArrayLength, GenericArray}; +use core::{cmp, ptr}; +use core::mem::ManuallyDrop; + +/// An iterator that moves out of a `GenericArray` +pub struct GenericArrayIter> { + // Invariants: index <= index_back <= N + // Only values in array[index..index_back] are alive at any given time. + // Values from array[..index] and array[index_back..] are already moved/dropped. + array: ManuallyDrop>, + index: usize, + index_back: usize, +} + +impl IntoIterator for GenericArray +where + N: ArrayLength, +{ + type Item = T; + type IntoIter = GenericArrayIter; + + fn into_iter(self) -> Self::IntoIter { + GenericArrayIter { + array: ManuallyDrop::new(self), + index: 0, + index_back: N::to_usize(), + } + } +} + +impl Drop for GenericArrayIter +where + N: ArrayLength, +{ + fn drop(&mut self) { + // Drop values that are still alive. + for p in &mut self.array[self.index..self.index_back] { + unsafe { + ptr::drop_in_place(p); + } + } + } +} + +impl Iterator for GenericArrayIter +where + N: ArrayLength, +{ + type Item = T; + + fn next(&mut self) -> Option { + if self.len() > 0 { + unsafe { + let p = self.array.get_unchecked(self.index); + self.index += 1; + Some(ptr::read(p)) + } + } else { + None + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } + + fn count(self) -> usize { + self.len() + } + + fn nth(&mut self, n: usize) -> Option { + // First consume values prior to the nth. + let ndrop = cmp::min(n, self.len()); + for p in &mut self.array[self.index..self.index + ndrop] { + self.index += 1; + unsafe { + ptr::drop_in_place(p); + } + } + + self.next() + } + + fn last(mut self) -> Option { + // Note, everything else will correctly drop first as `self` leaves scope. + self.next_back() + } +} + +impl DoubleEndedIterator for GenericArrayIter +where + N: ArrayLength, +{ + fn next_back(&mut self) -> Option { + if self.len() > 0 { + self.index_back -= 1; + unsafe { + let p = self.array.get_unchecked(self.index_back); + Some(ptr::read(p)) + } + } else { + None + } + } +} + +impl ExactSizeIterator for GenericArrayIter +where + N: ArrayLength, +{ + fn len(&self) -> usize { + self.index_back - self.index + } +} diff --git a/third_party/rust/generic-array-0.9.0/src/lib.rs b/third_party/rust/generic-array-0.9.0/src/lib.rs new file mode 100644 index 000000000000..ce478e5ec690 --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/src/lib.rs @@ -0,0 +1,464 @@ +//! This crate implements a structure that can be used as a generic array type.use +//! Core Rust array types `[T; N]` can't be used generically with +//! respect to `N`, so for example this: +//! +//! ```{should_fail} +//! struct Foo { +//! data: [T; N] +//! } +//! ``` +//! +//! won't work. +//! +//! **generic-array** exports a `GenericArray` type, which lets +//! the above be implemented as: +//! +//! ``` +//! # use generic_array::{ArrayLength, GenericArray}; +//! struct Foo> { +//! data: GenericArray +//! } +//! ``` +//! +//! The `ArrayLength` trait is implemented by default for +//! [unsigned integer types](../typenum/uint/index.html) from +//! [typenum](../typenum/index.html). +//! +//! For ease of use, an `arr!` macro is provided - example below: +//! +//! ``` +//! # #[macro_use] +//! # extern crate generic_array; +//! # extern crate typenum; +//! # fn main() { +//! let array = arr![u32; 1, 2, 3]; +//! assert_eq!(array[2], 3); +//! # } +//! ``` + +//#![deny(missing_docs)] +#![no_std] + +pub extern crate typenum; +#[cfg(feature = "serde")] +extern crate serde; + +mod hex; +mod impls; + +#[cfg(feature = "serde")] +pub mod impl_serde; + +use core::{mem, ptr, slice}; + +use core::marker::PhantomData; +use core::mem::ManuallyDrop; +pub use core::mem::transmute; +use core::ops::{Deref, DerefMut}; + +use typenum::bit::{B0, B1}; +use typenum::uint::{UInt, UTerm, Unsigned}; + +#[cfg_attr(test, macro_use)] +pub mod arr; +pub mod iter; +pub use iter::GenericArrayIter; + +/// Trait making `GenericArray` work, marking types to be used as length of an array +pub unsafe trait ArrayLength: Unsigned { + /// Associated type representing the array type for the number + type ArrayType; +} + +unsafe impl ArrayLength for UTerm { + #[doc(hidden)] + type ArrayType = (); +} + +/// Internal type used to generate a struct of appropriate size +#[allow(dead_code)] +#[repr(C)] +#[doc(hidden)] +pub struct GenericArrayImplEven { + parent1: U, + parent2: U, + _marker: PhantomData, +} + +impl Clone for GenericArrayImplEven { + fn clone(&self) -> GenericArrayImplEven { + GenericArrayImplEven { + parent1: self.parent1.clone(), + parent2: self.parent2.clone(), + _marker: PhantomData, + } + } +} + +impl Copy for GenericArrayImplEven {} + +/// Internal type used to generate a struct of appropriate size +#[allow(dead_code)] +#[repr(C)] +#[doc(hidden)] +pub struct GenericArrayImplOdd { + parent1: U, + parent2: U, + data: T, +} + +impl Clone for GenericArrayImplOdd { + fn clone(&self) -> GenericArrayImplOdd { + GenericArrayImplOdd { + parent1: self.parent1.clone(), + parent2: self.parent2.clone(), + data: self.data.clone(), + } + } +} + +impl Copy for GenericArrayImplOdd {} + +unsafe impl> ArrayLength for UInt { + #[doc(hidden)] + type ArrayType = GenericArrayImplEven; +} + +unsafe impl> ArrayLength for UInt { + #[doc(hidden)] + type ArrayType = GenericArrayImplOdd; +} + +/// Struct representing a generic array - `GenericArray` works like [T; N] +#[allow(dead_code)] +pub struct GenericArray> { + data: U::ArrayType, +} + +impl Deref for GenericArray +where + N: ArrayLength, +{ + type Target = [T]; + + fn deref(&self) -> &[T] { + unsafe { slice::from_raw_parts(self as *const Self as *const T, N::to_usize()) } + } +} + +impl DerefMut for GenericArray +where + N: ArrayLength, +{ + fn deref_mut(&mut self) -> &mut [T] { + unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize()) } + } +} + +struct ArrayBuilder> { + array: ManuallyDrop>, + position: usize, +} + +impl> ArrayBuilder { + fn new() -> ArrayBuilder { + ArrayBuilder { + array: ManuallyDrop::new(unsafe { mem::uninitialized() }), + position: 0, + } + } + + fn into_inner(self) -> GenericArray { + let array = unsafe { ptr::read(&self.array) }; + + mem::forget(self); + + ManuallyDrop::into_inner(array) + } +} + +impl> Drop for ArrayBuilder { + fn drop(&mut self) { + for value in self.array.iter_mut().take(self.position) { + unsafe { + ptr::drop_in_place(value); + } + } + } +} + +struct ArrayConsumer> { + array: ManuallyDrop>, + position: usize, +} + +impl> ArrayConsumer { + fn new(array: GenericArray) -> ArrayConsumer { + ArrayConsumer { + array: ManuallyDrop::new(array), + position: 0, + } + } +} + +impl> Drop for ArrayConsumer { + fn drop(&mut self) { + for i in self.position..N::to_usize() { + unsafe { + ptr::drop_in_place(self.array.get_unchecked_mut(i)); + } + } + } +} + +impl GenericArray +where + N: ArrayLength, +{ + /// Initializes a new `GenericArray` instance using the given function. + /// + /// If the generator function panics while initializing the array, + /// any already initialized elements will be dropped. + pub fn generate(f: F) -> GenericArray + where + F: Fn(usize) -> T, + { + let mut destination = ArrayBuilder::new(); + + for (i, dst) in destination.array.iter_mut().enumerate() { + unsafe { + ptr::write(dst, f(i)); + } + + destination.position += 1; + } + + destination.into_inner() + } + + /// Map a function over a slice to a `GenericArray`. + /// + /// The length of the slice *must* be equal to the length of the array. + #[inline] + pub fn map_slice T>(s: &[S], f: F) -> GenericArray { + assert_eq!(s.len(), N::to_usize()); + + Self::generate(|i| f(unsafe { s.get_unchecked(i) })) + } + + /// Maps a `GenericArray` to another `GenericArray`. + /// + /// If the mapping function panics, any already initialized elements in the new array + /// will be dropped, AND any unused elements in the source array will also be dropped. + pub fn map(self, f: F) -> GenericArray + where + F: Fn(T) -> U, + N: ArrayLength, + { + let mut source = ArrayConsumer::new(self); + let mut destination = ArrayBuilder::new(); + + for (dst, src) in destination.array.iter_mut().zip(source.array.iter()) { + unsafe { + ptr::write(dst, f(ptr::read(src))); + } + + source.position += 1; + destination.position += 1; + } + + destination.into_inner() + } + + /// Maps a `GenericArray` to another `GenericArray` by reference. + /// + /// If the mapping function panics, any already initialized elements will be dropped. + #[inline] + pub fn map_ref(&self, f: F) -> GenericArray + where + F: Fn(&T) -> U, + N: ArrayLength, + { + GenericArray::generate(|i| f(unsafe { self.get_unchecked(i) })) + } + + /// Combines two `GenericArray` instances and iterates through both of them, + /// initializing a new `GenericArray` with the result of the zipped mapping function. + /// + /// If the mapping function panics, any already initialized elements in the new array + /// will be dropped, AND any unused elements in the source arrays will also be dropped. + pub fn zip(self, rhs: GenericArray, f: F) -> GenericArray + where + F: Fn(T, B) -> U, + N: ArrayLength + ArrayLength, + { + let mut left = ArrayConsumer::new(self); + let mut right = ArrayConsumer::new(rhs); + + let mut destination = ArrayBuilder::new(); + + for (dst, (lhs, rhs)) in + destination.array.iter_mut().zip(left.array.iter().zip( + right.array.iter(), + )) + { + unsafe { + ptr::write(dst, f(ptr::read(lhs), ptr::read(rhs))); + } + + destination.position += 1; + left.position += 1; + right.position += 1; + } + + destination.into_inner() + } + + /// Combines two `GenericArray` instances and iterates through both of them by reference, + /// initializing a new `GenericArray` with the result of the zipped mapping function. + /// + /// If the mapping function panics, any already initialized elements will be dropped. + pub fn zip_ref(&self, rhs: &GenericArray, f: F) -> GenericArray + where + F: Fn(&T, &B) -> U, + N: ArrayLength + ArrayLength, + { + GenericArray::generate(|i| unsafe { + f(self.get_unchecked(i), rhs.get_unchecked(i)) + }) + } + + /// Extracts a slice containing the entire array. + #[inline] + pub fn as_slice(&self) -> &[T] { + self.deref() + } + + /// Extracts a mutable slice containing the entire array. + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.deref_mut() + } + + /// Converts slice to a generic array reference with inferred length; + /// + /// Length of the slice must be equal to the length of the array. + #[inline] + pub fn from_slice(slice: &[T]) -> &GenericArray { + assert_eq!(slice.len(), N::to_usize()); + + unsafe { &*(slice.as_ptr() as *const GenericArray) } + } + + /// Converts mutable slice to a mutable generic array reference + /// + /// Length of the slice must be equal to the length of the array. + #[inline] + pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray { + assert_eq!(slice.len(), N::to_usize()); + + unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray) } + } +} + +impl GenericArray +where + N: ArrayLength, +{ + /// Construct a `GenericArray` from a slice by cloning its content + /// + /// Length of the slice must be equal to the length of the array + #[inline] + pub fn clone_from_slice(list: &[T]) -> GenericArray { + Self::from_exact_iter(list.iter().cloned()).expect( + "Slice must be the same length as the array", + ) + } +} + +impl GenericArray +where + N: ArrayLength, +{ + pub fn from_exact_iter(iter: I) -> Option + where + I: IntoIterator, + ::IntoIter: ExactSizeIterator, + { + let iter = iter.into_iter(); + + if iter.len() == N::to_usize() { + let mut destination = ArrayBuilder::new(); + + for (dst, src) in destination.array.iter_mut().zip(iter.into_iter()) { + unsafe { + ptr::write(dst, src); + } + + destination.position += 1; + } + + let array = unsafe { ptr::read(&destination.array) }; + + mem::forget(destination); + + Some(ManuallyDrop::into_inner(array)) + } else { + None + } + } +} + +impl ::core::iter::FromIterator for GenericArray +where + N: ArrayLength, + T: Default, +{ + fn from_iter(iter: I) -> GenericArray + where + I: IntoIterator, + { + let mut destination = ArrayBuilder::new(); + + let defaults = ::core::iter::repeat(()).map(|_| T::default()); + + for (dst, src) in destination.array.iter_mut().zip( + iter.into_iter().chain(defaults), + ) + { + unsafe { + ptr::write(dst, src); + } + } + + destination.into_inner() + } +} + +#[cfg(test)] +mod test { + // Compile with: + // cargo rustc --lib --profile test --release -- + // -C target-cpu=native -C opt-level=3 --emit asm + // and view the assembly to make sure test_assembly generates + // SIMD instructions instead of a niave loop. + + #[inline(never)] + pub fn black_box(val: T) -> T { + use core::{mem, ptr}; + + let ret = unsafe { ptr::read_volatile(&val) }; + mem::forget(val); + ret + } + + #[test] + fn test_assembly() { + let a = black_box(arr![i32; 1, 3, 5, 7]); + let b = black_box(arr![i32; 2, 4, 6, 8]); + + let c = a.zip_ref(&b, |l, r| l + r); + + assert_eq!(c, arr![i32; 3, 7, 11, 15]); + } +} diff --git a/third_party/rust/generic-array-0.9.0/tests/hex.rs b/third_party/rust/generic-array-0.9.0/tests/hex.rs new file mode 100644 index 000000000000..aed69e424979 --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/tests/hex.rs @@ -0,0 +1,44 @@ +#[macro_use] +extern crate generic_array; +extern crate typenum; + +use generic_array::GenericArray; +use std::str::from_utf8; +use typenum::U2048; + + +#[test] +fn short_lower_hex() { + let ar = arr![u8; 10, 20, 30]; + assert_eq!(format!("{:x}", ar), "0a141e"); +} + +#[test] +fn short_upper_hex() { + let ar = arr![u8; 30, 20, 10]; + assert_eq!(format!("{:X}", ar), "1E140A"); +} + +#[test] +fn long_lower_hex() { + let ar = GenericArray::::default(); + assert_eq!(format!("{:x}", ar), from_utf8(&[b'0'; 4096]).unwrap()); +} + +#[test] +fn long_upper_hex() { + let ar = GenericArray::::default(); + assert_eq!(format!("{:X}", ar), from_utf8(&[b'0'; 4096]).unwrap()); +} + +#[test] +fn truncated_lower_hex() { + let ar = arr![u8; 10, 20, 30, 40, 50]; + assert_eq!(format!("{:.2x}", ar), "0a14"); +} + +#[test] +fn truncated_upper_hex() { + let ar = arr![u8; 30, 20, 10, 17, 0]; + assert_eq!(format!("{:.4X}", ar), "1E140A11"); +} diff --git a/third_party/rust/generic-array-0.9.0/tests/import_name.rs b/third_party/rust/generic-array-0.9.0/tests/import_name.rs new file mode 100644 index 000000000000..27653c9a85d7 --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/tests/import_name.rs @@ -0,0 +1,10 @@ +#[macro_use] +extern crate generic_array as gen_arr; + +use gen_arr::typenum; + +#[test] +fn test_different_crate_name() { + let _: gen_arr::GenericArray = arr![u32; 0, 1, 2, 3]; + let _: gen_arr::GenericArray = arr![u32;]; +} diff --git a/third_party/rust/generic-array-0.9.0/tests/mod.rs b/third_party/rust/generic-array-0.9.0/tests/mod.rs new file mode 100644 index 000000000000..2a2f2e15f7c5 --- /dev/null +++ b/third_party/rust/generic-array-0.9.0/tests/mod.rs @@ -0,0 +1,169 @@ +#![recursion_limit="128"] +#![no_std] +#[macro_use] +extern crate generic_array; +use core::cell::Cell; +use core::ops::Drop; +use generic_array::GenericArray; +use generic_array::typenum::{U1, U3, U4, U97}; + +#[test] +fn test() { + let mut list97 = [0; 97]; + for i in 0..97 { + list97[i] = i as i32; + } + let l: GenericArray = GenericArray::clone_from_slice(&list97); + assert_eq!(l[0], 0); + assert_eq!(l[1], 1); + assert_eq!(l[32], 32); + assert_eq!(l[56], 56); +} + +#[test] +fn test_drop() { + #[derive(Clone)] + struct TestDrop<'a>(&'a Cell); + + impl<'a> Drop for TestDrop<'a> { + fn drop(&mut self) { + self.0.set(self.0.get() + 1); + } + } + + let drop_counter = Cell::new(0); + { + let _: GenericArray = + arr![TestDrop; TestDrop(&drop_counter), + TestDrop(&drop_counter), + TestDrop(&drop_counter)]; + } + assert_eq!(drop_counter.get(), 3); +} + +#[test] +fn test_arr() { + let test: GenericArray = arr![u32; 1, 2, 3]; + assert_eq!(test[1], 2); +} + +#[test] +fn test_copy() { + let test = arr![u32; 1, 2, 3]; + let test2 = test; + // if GenericArray is not copy, this should fail as a use of a moved value + assert_eq!(test[1], 2); + assert_eq!(test2[0], 1); +} + +#[test] +fn test_iter_flat_map() { + assert!((0..5).flat_map(|i| arr![i32; 2 * i, 2 * i + 1]).eq(0..10)); +} + +#[derive(Debug, PartialEq, Eq)] +struct NoClone(T); + +#[test] +fn test_from_slice() { + let arr = [1, 2, 3, 4]; + let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]); + assert_eq!(&arr[..3], gen_arr.as_slice()); + let arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)]; + let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]); + assert_eq!(&arr[..3], gen_arr.as_slice()); +} + +#[test] +fn test_from_mut_slice() { + let mut arr = [1, 2, 3, 4]; + { + let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]); + gen_arr[2] = 10; + } + assert_eq!(arr, [1, 2, 10, 4]); + let mut arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)]; + { + let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]); + gen_arr[2] = NoClone(10); + } + assert_eq!(arr, [NoClone(1), NoClone(2), NoClone(10), NoClone(4)]); +} + +#[test] +fn test_default() { + let arr = GenericArray::::default(); + assert_eq!(arr[0], 0); +} + +#[test] +fn test_from() { + let data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]; + let garray: GenericArray<(usize, usize, usize), U3> = data.into(); + assert_eq!(&data, garray.as_slice()); +} + +#[test] +fn test_unit_macro() { + let arr = arr![f32; 3.14]; + assert_eq!(arr[0], 3.14); +} + +#[test] +fn test_empty_macro() { + let _arr = arr![f32;]; +} + +#[test] +fn test_cmp() { + arr![u8; 0x00].cmp(&arr![u8; 0x00]); +} + +/// This test should cause a helpful compile error if uncommented. +// #[test] +// fn test_empty_macro2(){ +// let arr = arr![]; +// } +#[cfg(feature = "serde")] +mod impl_serde { + extern crate serde_json; + + use generic_array::GenericArray; + use generic_array::typenum::U6; + + #[test] + fn test_serde_implementation() { + let array: GenericArray = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0]; + let string = serde_json::to_string(&array).unwrap(); + assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]"); + + let test_array: GenericArray = serde_json::from_str(&string).unwrap(); + assert_eq!(test_array, array); + } +} + +#[test] +fn test_map() { + let b: GenericArray = GenericArray::generate(|i| i as i32 * 4).map(|x| x - 3); + + assert_eq!(b, arr![i32; -3, 1, 5, 9]); +} + +#[test] +fn test_zip() { + let a: GenericArray<_, U4> = GenericArray::generate(|i| i + 1); + let b: GenericArray<_, U4> = GenericArray::generate(|i| i as i32 * 4); + + let c = a.zip(b, |r, l| r as i32 + l); + + assert_eq!(c, arr![i32; 1, 6, 11, 16]); +} + +#[test] +fn test_from_iter() { + use core::iter::repeat; + + let a: GenericArray<_, U4> = repeat(11).take(3).collect(); + + assert_eq!(a, arr![i32; 11, 11, 11, 0]); +} diff --git a/third_party/rust/generic-array/.cargo-checksum.json b/third_party/rust/generic-array/.cargo-checksum.json index 6616b505b573..490e4475dfbd 100644 --- a/third_party/rust/generic-array/.cargo-checksum.json +++ b/third_party/rust/generic-array/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"87ff65d640c137c26d338f96e21e769af1e1b2e7fa615b40a1bcc755448bb118","LICENSE":"ad4fcfaf8d5b12b97409c137a03d4a4e4b21024c65c54f976cc3b609c1bd5b0f","README.md":"9a1a45416eac57050036b13df6ec84d21d555e820726af3c782896bd9d37d94b","rustfmt.toml":"2a298b4ce1fe6e16b8f281a0035567b8eb15042ed3062729fd28224f29c2f75a","src/arr.rs":"cc1ea0a9ef6a524b90767cc8a89f6b939394a2948a645ed313c0bf5ce5a258a4","src/hex.rs":"bfbf304fb4dea6f7edc0569b38bf2ac7657ce089c5761891321722509e3b5076","src/impl_serde.rs":"805885478728b3c205b842d46deb377b7dd6dd4c4c50254064431f49f0981a2a","src/impls.rs":"8c54e294a82a2bf344bdcb9949b8a84903fb65698d6b1b1e0ab9f5e7847be64f","src/iter.rs":"e52217f04d0dc046f13ef2e3539b90eabd4d55bb85cf40f76ba0bf86d5e55ef0","src/lib.rs":"da93fa505eee94b40fce0fe98e26ed3bb4d2bc4d4869af01598b6e54fc9c0f8d","tests/hex.rs":"e909bc0564e7d52c5fcf172dfc0fac7085010c6a21d38581bf73a54ab2e256e1","tests/import_name.rs":"1235729ecbde47fc9a38b3bf35c750a53ed55e3cf967c9d2b24fd759dc9e9e0c","tests/mod.rs":"f4100c5338906c038636f98f4d2b3d272f59580662afa89d915eafb96d7bbcf9"},"package":"ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"} \ No newline at end of file +{"files":{"CHANGELOG.md":"aa938a1a7581e59cbb554b44cc2dcf628cc1af9ddee6dccd53f557ed8d62775e","Cargo.toml":"df66f4832231be648f616c6d5ef1bacf25b40ff5118c7075554a4b41ce1d8ab1","LICENSE":"c09aae9d3c77b531f56351a9947bc7446511d6b025b3255312d3e3442a9a7583","README.md":"aad2a8508f8ae6b009d04d388bffb751875d4cfdcc6f3398212c65cc3c390d03","rustfmt.toml":"13d771354ddee15d5aa5a168fd6965c3c0ee7aa7ce75cdd5e3b82852cdac5123","src/arr.rs":"5fee5550800b890383c1dd80e00a0a568475a8599e7678e143740c941e98099d","src/functional.rs":"2437c360c645d8a9816a3b13531f23b005d1aed3ef7b1d9bcc9b2859b1d56826","src/hex.rs":"438288cf41fad3fd40ce60eb893cd038e9a88e450bab0189fe4dba8ce833a686","src/impl_serde.rs":"2cab2f808ba000c214a3ded9f43b4d5363114fe57c2c7abf545345b8b749f0db","src/impls.rs":"a7fbfc134e2d716d3a816c4b7b8aa8376172fb7f2caf91bbb02a52595a45d253","src/iter.rs":"156f798c82bc0d5e2c9a0a7777acc156bfdda793b64295ad7495cc5daa5ecb97","src/lib.rs":"a6e6a869ed40ac944e7817d571b8357eab168b132ad0c2418ab4f3f5cdeede69","src/sequence.rs":"63813c9e305b6642ac29f0ba3dd70d7db86e27fc58b31e7508c68ea52c060e82","tests/arr.rs":"22d332fcb5e0314980ddc952af0265125cf53bb9cb8b546a9dcaec2e29bfc3b0","tests/generics.rs":"491c9351fd973ff2b7bc72e78d3069cf3ed3fcd2f9180558ab027099605fa147","tests/hex.rs":"fd428c2558da2f1e2cf229af2e40e5b35a2094b3306312ac41943d25a85b7de1","tests/import_name.rs":"c9439c7d7531ce79419b0d413d729ea4321887c091bd9be8b18e6c2413021ed0","tests/iter.rs":"edf27c43ed13bf8cba2cd01de2fd7b6451c1226c8ad8331880996248e7f14d12","tests/mod.rs":"fca2966183ccd1d1681f91a845773911ab61f618bd412470612fac240ecfe0db"},"package":"3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592"} \ No newline at end of file diff --git a/third_party/rust/generic-array/CHANGELOG.md b/third_party/rust/generic-array/CHANGELOG.md new file mode 100644 index 000000000000..f8ee86b8e678 --- /dev/null +++ b/third_party/rust/generic-array/CHANGELOG.md @@ -0,0 +1,48 @@ +* **`0.12.0`** + * Allow trailing commas in `arr!` macro. + * **BREAKING**: Serialize `GenericArray` using `serde` tuples, instead of variable-length sequences. This may not be compatible with old serialized data. + +* **`0.11.0`** + * **BREAKING** Redesign `GenericSequence` with an emphasis on use in generic type parameters. + * Add `MappedGenericSequence` and `FunctionalSequence` + * Implements optimized `map`, `zip` and `fold` for `GenericArray`, `&GenericArray` and `&mut GenericArray` + * **BREAKING** Remove `map_ref`, `zip_ref` and `map_slice` + * `map_slice` is now equivalent to `GenericArray::from_iter(slice.iter().map(...))` +* **`0.10.0`** + * Add `GenericSequence`, `Lengthen`, `Shorten`, `Split` and `Concat` traits. + * Redefine `transmute` to avert errors. +* **`0.9.0`** + * Rewrite construction methods to be well-defined in panic situations, correctly dropping elements. + * `NoDrop` crate replaced by `ManuallyDrop` as it became stable in Rust core. + * Add optimized `map`/`map_ref` and `zip`/`zip_ref` methods to `GenericArray` +* **`0.8.0`** + * Implement `AsRef`, `AsMut`, `Borrow`, `BorrowMut`, `Hash` for `GenericArray` + * Update `serde` to `1.0` + * Update `typenum` + * Make macro `arr!` non-cloning + * Implement `From<[T; N]>` up to `N=32` + * Fix #45 +* **`0.7.0`** + * Upgrade `serde` to `0.9` + * Make `serde` with `no_std` + * Implement `PartialOrd`/`Ord` for `GenericArray` +* **`0.6.0`** + * Fixed #30 + * Implement `Default` for `GenericArray` + * Implement `LowerHex` and `UpperHex` for `GenericArray` + * Use `precision` formatting field in hex representation + * Add `as_slice`, `as_mut_slice` + * Remove `GenericArray::new` in favor of `Default` trait + * Add `from_slice` and `from_mut_slice` + * `no_std` and `core` for crate. +* **`0.5.0`** + * Update `serde` + * remove `no_std` feature, fixed #19 +* **`0.4.0`** + * Re-export `typenum` +* **`0.3.0`** + * Implement `IntoIter` for `GenericArray` + * Add `map` method + * Add optional `serde` (de)serialization support feature. +* **`< 0.3.0`** + * Initial implementation in late 2015 diff --git a/third_party/rust/generic-array/Cargo.toml b/third_party/rust/generic-array/Cargo.toml index 07c6064694ee..6bf03b85f834 100644 --- a/third_party/rust/generic-array/Cargo.toml +++ b/third_party/rust/generic-array/Cargo.toml @@ -12,21 +12,29 @@ [package] name = "generic-array" -version = "0.9.0" -authors = ["Bartłomiej Kamiński "] +version = "0.12.0" +authors = ["Bartłomiej Kamiński ", "Aaron Trent "] description = "Generic types implementing functionality of arrays" documentation = "http://fizyk20.github.io/generic-array/generic_array/" +readme = "README.md" +keywords = ["generic", "array"] +categories = ["data-structures", "no-std"] license = "MIT" repository = "https://github.com/fizyk20/generic-array.git" [lib] name = "generic_array" -[dependencies.typenum] -version = "1.9" - [dependencies.serde] version = "1.0" optional = true default-features = false + +[dependencies.typenum] +version = "1.10" +[dev-dependencies.bincode] +version = "1.0" + [dev-dependencies.serde_json] version = "1.0" +[badges.travis-ci] +repository = "fizyk20/generic-array" diff --git a/third_party/rust/generic-array/LICENSE b/third_party/rust/generic-array/LICENSE index 5968bccccf99..6d318946df8e 100644 --- a/third_party/rust/generic-array/LICENSE +++ b/third_party/rust/generic-array/LICENSE @@ -1,21 +1,21 @@ -The MIT License (MIT) - -Copyright (c) 2015 Bartłomiej Kamiński - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +The MIT License (MIT) + +Copyright (c) 2015 Bartłomiej Kamiński + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/third_party/rust/generic-array/README.md b/third_party/rust/generic-array/README.md index 0864ed62736a..64dd84faaf88 100644 --- a/third_party/rust/generic-array/README.md +++ b/third_party/rust/generic-array/README.md @@ -1,34 +1,34 @@ -[![Crates.io](https://img.shields.io/crates/v/generic-array.svg)](https://crates.io/crates/generic-array) -[![Build Status](https://travis-ci.org/fizyk20/generic-array.svg?branch=master)](https://travis-ci.org/fizyk20/generic-array) -# generic-array - -This crate implements generic array types for Rust. - -[Documentation](http://fizyk20.github.io/generic-array/generic_array/) - -## Usage - -The Rust arrays `[T; N]` are problematic in that they can't be used generically with respect to `N`, so for example this won't work: - -```rust -struct Foo { - data: [i32; N] -} -``` - -**generic-array** defines a new trait `ArrayLength` and a struct `GenericArray>`, which let the above be implemented as: - -```rust -struct Foo> { - data: GenericArray -} -``` - -To actually define a type implementing `ArrayLength`, you can use unsigned integer types defined in [typenum](https://github.com/paholg/typenum) crate - for example, `GenericArray` would work almost like `[T; 5]` :) - -In version 0.1.1 an `arr!` macro was introduced, allowing for creation of arrays as shown below: - -```rust -let array = arr![u32; 1, 2, 3]; -assert_eq!(array[2], 3); -``` +[![Crates.io](https://img.shields.io/crates/v/generic-array.svg)](https://crates.io/crates/generic-array) +[![Build Status](https://travis-ci.org/fizyk20/generic-array.svg?branch=master)](https://travis-ci.org/fizyk20/generic-array) +# generic-array + +This crate implements generic array types for Rust. + +[Documentation](http://fizyk20.github.io/generic-array/generic_array/) + +## Usage + +The Rust arrays `[T; N]` are problematic in that they can't be used generically with respect to `N`, so for example this won't work: + +```rust +struct Foo { + data: [i32; N] +} +``` + +**generic-array** defines a new trait `ArrayLength` and a struct `GenericArray>`, which let the above be implemented as: + +```rust +struct Foo> { + data: GenericArray +} +``` + +To actually define a type implementing `ArrayLength`, you can use unsigned integer types defined in [typenum](https://github.com/paholg/typenum) crate - for example, `GenericArray` would work almost like `[T; 5]` :) + +In version 0.1.1 an `arr!` macro was introduced, allowing for creation of arrays as shown below: + +```rust +let array = arr![u32; 1, 2, 3]; +assert_eq!(array[2], 3); +``` diff --git a/third_party/rust/generic-array/rustfmt.toml b/third_party/rust/generic-array/rustfmt.toml index 3dc0db27b317..a46e4b2bdbee 100644 --- a/third_party/rust/generic-array/rustfmt.toml +++ b/third_party/rust/generic-array/rustfmt.toml @@ -1,3 +1,3 @@ -reorder_imports = true -reorder_imported_names = true -use_try_shorthand = true +reorder_imports = true +reorder_imported_names = true +use_try_shorthand = true diff --git a/third_party/rust/generic-array/src/arr.rs b/third_party/rust/generic-array/src/arr.rs index 51d87f63ca7e..a07d129ad3fa 100644 --- a/third_party/rust/generic-array/src/arr.rs +++ b/third_party/rust/generic-array/src/arr.rs @@ -1,57 +1,57 @@ -//! Implementation for `arr!` macro. - -use super::ArrayLength; -use core::ops::Add; -use typenum::U1; - -/// Helper trait for `arr!` macro -pub trait AddLength>: ArrayLength { - /// Resulting length - type Output: ArrayLength; -} - -impl AddLength for N1 -where - N1: ArrayLength + Add, - N2: ArrayLength, - >::Output: ArrayLength, -{ - type Output = >::Output; -} - -/// Helper type for `arr!` macro -pub type Inc = >::Output; - -#[doc(hidden)] -#[macro_export] -macro_rules! arr_impl { - ($T:ty; $N:ty, [$($x:expr),*], []) => ({ - unsafe { $crate::transmute::<_, $crate::GenericArray<$T, $N>>([$($x),*]) } - }); - ($T:ty; $N:ty, [], [$x1:expr]) => ( - arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], []) - ); - ($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => ( - arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [$($x),*]) - ); - ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => ( - arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),*, $x1 as $T], []) - ); - ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => ( - arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),*, $x1 as $T], [$($x),*]) - ); -} - -/// Macro allowing for easy generation of Generic Arrays. -/// Example: `let test = arr![u32; 1, 2, 3];` -#[macro_export] -macro_rules! arr { - ($T:ty;) => ({ - unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) } - }); - ($T:ty; $($x:expr),*) => ( - arr_impl!($T; $crate::typenum::U0, [], [$($x),*]) - ); - ($($x:expr,)+) => (arr![$($x),*]); - () => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`") -} +//! Implementation for `arr!` macro. + +use super::ArrayLength; +use core::ops::Add; +use typenum::U1; + +/// Helper trait for `arr!` macro +pub trait AddLength>: ArrayLength { + /// Resulting length + type Output: ArrayLength; +} + +impl AddLength for N1 +where + N1: ArrayLength + Add, + N2: ArrayLength, + >::Output: ArrayLength, +{ + type Output = >::Output; +} + +/// Helper type for `arr!` macro +pub type Inc = >::Output; + +#[doc(hidden)] +#[macro_export] +macro_rules! arr_impl { + ($T:ty; $N:ty, [$($x:expr),*], []) => ({ + unsafe { $crate::transmute::<_, $crate::GenericArray<$T, $N>>([$($x),*]) } + }); + ($T:ty; $N:ty, [], [$x1:expr]) => ( + arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], []) + ); + ($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => ( + arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [$($x),+]) + ); + ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => ( + arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1 as $T], []) + ); + ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => ( + arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1 as $T], [$($x),+]) + ); +} + +/// Macro allowing for easy generation of Generic Arrays. +/// Example: `let test = arr![u32; 1, 2, 3];` +#[macro_export] +macro_rules! arr { + ($T:ty; $(,)*) => ({ + unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) } + }); + ($T:ty; $($x:expr),* $(,)*) => ( + arr_impl!($T; $crate::typenum::U0, [], [$($x),*]) + ); + ($($x:expr,)+) => (arr![$($x),*]); + () => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`") +} diff --git a/third_party/rust/generic-array/src/functional.rs b/third_party/rust/generic-array/src/functional.rs new file mode 100644 index 000000000000..d161a83cacc3 --- /dev/null +++ b/third_party/rust/generic-array/src/functional.rs @@ -0,0 +1,94 @@ +//! Functional programming with generic sequences +//! +//! Please see `tests/generics.rs` for examples of how to best use these in your generic functions. + +use super::ArrayLength; +use core::iter::FromIterator; +use sequence::*; + +/// Defines the relationship between one generic sequence and another, +/// for operations such as `map` and `zip`. +pub unsafe trait MappedGenericSequence: GenericSequence +where + Self::Length: ArrayLength, +{ + /// Mapped sequence type + type Mapped: GenericSequence; +} + +unsafe impl<'a, T, U, S: MappedGenericSequence> MappedGenericSequence for &'a S +where + &'a S: GenericSequence, + S: GenericSequence>::Length>, + >::Length: ArrayLength, +{ + type Mapped = >::Mapped; +} + +unsafe impl<'a, T, U, S: MappedGenericSequence> MappedGenericSequence for &'a mut S +where + &'a mut S: GenericSequence, + S: GenericSequence>::Length>, + >::Length: ArrayLength, +{ + type Mapped = >::Mapped; +} + +/// Accessor type for a mapped generic sequence +pub type MappedSequence = + <>::Mapped as GenericSequence>::Sequence; + +/// Defines functional programming methods for generic sequences +pub unsafe trait FunctionalSequence: GenericSequence { + /// Maps a `GenericSequence` to another `GenericSequence`. + /// + /// If the mapping function panics, any already initialized elements in the new sequence + /// will be dropped, AND any unused elements in the source sequence will also be dropped. + fn map(self, f: F) -> MappedSequence + where + Self: MappedGenericSequence, + Self::Length: ArrayLength, + F: FnMut(Self::Item) -> U, + { + FromIterator::from_iter(self.into_iter().map(f)) + } + + /// Combines two `GenericSequence` instances and iterates through both of them, + /// initializing a new `GenericSequence` with the result of the zipped mapping function. + /// + /// If the mapping function panics, any already initialized elements in the new sequence + /// will be dropped, AND any unused elements in the source sequences will also be dropped. + #[inline] + fn zip(self, rhs: Rhs, f: F) -> MappedSequence + where + Self: MappedGenericSequence, + Rhs: MappedGenericSequence>, + Self::Length: ArrayLength + ArrayLength, + Rhs: GenericSequence, + F: FnMut(Self::Item, Rhs::Item) -> U, + { + rhs.inverted_zip2(self, f) + } + + /// Folds (or reduces) a sequence of data into a single value. + /// + /// If the fold function panics, any unused elements will be dropped. + fn fold(self, init: U, f: F) -> U + where + F: FnMut(U, Self::Item) -> U, + { + self.into_iter().fold(init, f) + } +} + +unsafe impl<'a, T, S: GenericSequence> FunctionalSequence for &'a S +where + &'a S: GenericSequence, +{ +} + +unsafe impl<'a, T, S: GenericSequence> FunctionalSequence for &'a mut S +where + &'a mut S: GenericSequence, +{ +} diff --git a/third_party/rust/generic-array/src/hex.rs b/third_party/rust/generic-array/src/hex.rs index 1ce5332f781e..09a6608e37ce 100644 --- a/third_party/rust/generic-array/src/hex.rs +++ b/third_party/rust/generic-array/src/hex.rs @@ -1,101 +1,102 @@ -//! Generic array are commonly used as a return value for hash digests, so -//! it's a good idea to allow to hexlify them easily. This module implements -//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits. -//! -//! Example: -//! -//! ```rust -//! # #[macro_use] -//! # extern crate generic_array; -//! # extern crate typenum; -//! # fn main() { -//! let array = arr![u8; 10, 20, 30]; -//! assert_eq!(format!("{:x}", array), "0a141e"); -//! # } -//! ``` -//! - -use {ArrayLength, GenericArray}; -use core::fmt; -use core::ops::Add; -use core::str; -use typenum::*; - -static LOWER_CHARS: &'static [u8] = b"0123456789abcdef"; -static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF"; - -impl> fmt::LowerHex for GenericArray -where - T: Add, - >::Output: ArrayLength, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let max_digits = f.precision().unwrap_or_else(|| self.len()); - - if T::to_usize() < 1024 { - // For small arrays use a stack allocated - // buffer of 2x number of bytes - let mut res = GenericArray::>::default(); - - for (i, c) in self.iter().take(max_digits).enumerate() { - res[i * 2] = LOWER_CHARS[(c >> 4) as usize]; - res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize]; - } - f.write_str( - unsafe { str::from_utf8_unchecked(&res[..max_digits * 2]) }, - )?; - } else { - // For large array use chunks of up to 1024 bytes (2048 hex chars) - let mut buf = [0u8; 2048]; - - for chunk in self[..max_digits].chunks(1024) { - for (i, c) in chunk.iter().enumerate() { - buf[i * 2] = LOWER_CHARS[(c >> 4) as usize]; - buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize]; - } - f.write_str(unsafe { - str::from_utf8_unchecked(&buf[..chunk.len() * 2]) - })?; - } - } - Ok(()) - } -} - -impl> fmt::UpperHex for GenericArray -where - T: Add, - >::Output: ArrayLength, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let max_digits = f.precision().unwrap_or_else(|| self.len()); - - if T::to_usize() < 1024 { - // For small arrays use a stack allocated - // buffer of 2x number of bytes - let mut res = GenericArray::>::default(); - - for (i, c) in self.iter().take(max_digits).enumerate() { - res[i * 2] = UPPER_CHARS[(c >> 4) as usize]; - res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize]; - } - f.write_str( - unsafe { str::from_utf8_unchecked(&res[..max_digits * 2]) }, - )?; - } else { - // For large array use chunks of up to 1024 bytes (2048 hex chars) - let mut buf = [0u8; 2048]; - - for chunk in self[..max_digits].chunks(1024) { - for (i, c) in chunk.iter().enumerate() { - buf[i * 2] = UPPER_CHARS[(c >> 4) as usize]; - buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize]; - } - f.write_str(unsafe { - str::from_utf8_unchecked(&buf[..chunk.len() * 2]) - })?; - } - } - Ok(()) - } -} +//! Generic array are commonly used as a return value for hash digests, so +//! it's a good idea to allow to hexlify them easily. This module implements +//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits. +//! +//! Example: +//! +//! ```rust +//! # #[macro_use] +//! # extern crate generic_array; +//! # extern crate typenum; +//! # fn main() { +//! let array = arr![u8; 10, 20, 30]; +//! assert_eq!(format!("{:x}", array), "0a141e"); +//! # } +//! ``` +//! + +use {ArrayLength, GenericArray}; +use core::cmp::min; +use core::fmt; +use core::ops::Add; +use core::str; +use typenum::*; + +static LOWER_CHARS: &'static [u8] = b"0123456789abcdef"; +static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF"; + +impl> fmt::LowerHex for GenericArray +where + T: Add, + >::Output: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let max_digits = f.precision().unwrap_or_else(|| self.len() * 2); + let max_hex = (max_digits >> 1) + (max_digits & 1); + + if T::to_usize() < 1024 { + // For small arrays use a stack allocated + // buffer of 2x number of bytes + let mut res = GenericArray::>::default(); + + for (i, c) in self.iter().take(max_hex).enumerate() { + res[i * 2] = LOWER_CHARS[(c >> 4) as usize]; + res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize]; + } + f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?; + } else { + // For large array use chunks of up to 1024 bytes (2048 hex chars) + let mut buf = [0u8; 2048]; + let mut digits_left = max_digits; + + for chunk in self[..max_hex].chunks(1024) { + for (i, c) in chunk.iter().enumerate() { + buf[i * 2] = LOWER_CHARS[(c >> 4) as usize]; + buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize]; + } + let n = min(chunk.len() * 2, digits_left); + f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?; + digits_left -= n; + } + } + Ok(()) + } +} + +impl> fmt::UpperHex for GenericArray +where + T: Add, + >::Output: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let max_digits = f.precision().unwrap_or_else(|| self.len() * 2); + let max_hex = (max_digits >> 1) + (max_digits & 1); + + if T::to_usize() < 1024 { + // For small arrays use a stack allocated + // buffer of 2x number of bytes + let mut res = GenericArray::>::default(); + + for (i, c) in self.iter().take(max_hex).enumerate() { + res[i * 2] = UPPER_CHARS[(c >> 4) as usize]; + res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize]; + } + f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?; + } else { + // For large array use chunks of up to 1024 bytes (2048 hex chars) + let mut buf = [0u8; 2048]; + let mut digits_left = max_digits; + + for chunk in self[..max_hex].chunks(1024) { + for (i, c) in chunk.iter().enumerate() { + buf[i * 2] = UPPER_CHARS[(c >> 4) as usize]; + buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize]; + } + let n = min(chunk.len() * 2, digits_left); + f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?; + digits_left -= n; + } + } + Ok(()) + } +} diff --git a/third_party/rust/generic-array/src/impl_serde.rs b/third_party/rust/generic-array/src/impl_serde.rs index fd7f4908053b..7bf20ba0132e 100644 --- a/third_party/rust/generic-array/src/impl_serde.rs +++ b/third_party/rust/generic-array/src/impl_serde.rs @@ -1,68 +1,108 @@ -//! Serde serialization/deserialization implementation - -use {ArrayLength, GenericArray}; -use core::fmt; -use core::marker::PhantomData; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde::de::{self, SeqAccess, Visitor}; - -impl Serialize for GenericArray -where - T: Serialize, - N: ArrayLength, -{ - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.collect_seq(self.iter()) - } -} - -struct GAVisitor { - _t: PhantomData, - _n: PhantomData, -} - -impl<'de, T, N> Visitor<'de> for GAVisitor -where - T: Deserialize<'de> + Default, - N: ArrayLength, -{ - type Value = GenericArray; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("struct GenericArray") - } - - fn visit_seq(self, mut seq: A) -> Result, A::Error> - where - A: SeqAccess<'de>, - { - let mut result = GenericArray::default(); - for i in 0..N::to_usize() { - result[i] = seq.next_element()?.ok_or_else( - || de::Error::invalid_length(i, &self), - )?; - } - Ok(result) - } -} - -impl<'de, T, N> Deserialize<'de> for GenericArray -where - T: Deserialize<'de> + Default, - N: ArrayLength, -{ - fn deserialize(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - let visitor = GAVisitor { - _t: PhantomData, - _n: PhantomData, - }; - deserializer.deserialize_seq(visitor) - } -} +//! Serde serialization/deserialization implementation + +use core::fmt; +use core::marker::PhantomData; +use serde::de::{self, SeqAccess, Visitor}; +use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer}; +use {ArrayLength, GenericArray}; + +impl Serialize for GenericArray +where + T: Serialize, + N: ArrayLength, +{ + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut tup = serializer.serialize_tuple(N::to_usize())?; + for el in self { + tup.serialize_element(el)?; + } + + tup.end() + } +} + +struct GAVisitor { + _t: PhantomData, + _n: PhantomData, +} + +impl<'de, T, N> Visitor<'de> for GAVisitor +where + T: Deserialize<'de> + Default, + N: ArrayLength, +{ + type Value = GenericArray; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("struct GenericArray") + } + + fn visit_seq(self, mut seq: A) -> Result, A::Error> + where + A: SeqAccess<'de>, + { + let mut result = GenericArray::default(); + for i in 0..N::to_usize() { + result[i] = seq + .next_element()? + .ok_or_else(|| de::Error::invalid_length(i, &self))?; + } + Ok(result) + } +} + +impl<'de, T, N> Deserialize<'de> for GenericArray +where + T: Deserialize<'de> + Default, + N: ArrayLength, +{ + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let visitor = GAVisitor { + _t: PhantomData, + _n: PhantomData, + }; + deserializer.deserialize_tuple(N::to_usize(), visitor) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use bincode; + use typenum; + + #[test] + fn test_serialize() { + let array = GenericArray::::default(); + let serialized = bincode::serialize(&array); + assert!(serialized.is_ok()); + } + + #[test] + fn test_deserialize() { + let mut array = GenericArray::::default(); + array[0] = 1; + array[1] = 2; + let serialized = bincode::serialize(&array).unwrap(); + let deserialized = bincode::deserialize::>(&array); + assert!(deserialized.is_ok()); + let array = deserialized.unwrap(); + assert_eq!(array[0], 1); + assert_eq!(array[1], 2); + } + + #[test] + fn test_serialized_size() { + let array = GenericArray::::default(); + let size = bincode::serialized_size(&array).unwrap(); + assert_eq!(size, 1); + } + +} diff --git a/third_party/rust/generic-array/src/impls.rs b/third_party/rust/generic-array/src/impls.rs index 3055876661a6..db2db58005c7 100644 --- a/third_party/rust/generic-array/src/impls.rs +++ b/third_party/rust/generic-array/src/impls.rs @@ -1,171 +1,173 @@ -use super::{ArrayLength, GenericArray}; -use core::borrow::{Borrow, BorrowMut}; -use core::cmp::Ordering; -use core::fmt::{self, Debug}; -use core::hash::{Hash, Hasher}; - -impl Default for GenericArray -where - N: ArrayLength, -{ - #[inline] - fn default() -> Self { - Self::generate(|_| T::default()) - } -} - -impl Clone for GenericArray -where - N: ArrayLength, -{ - fn clone(&self) -> GenericArray { - self.map_ref(|x| x.clone()) - } -} - -impl Copy for GenericArray -where - N: ArrayLength, - N::ArrayType: Copy, -{ -} - -impl PartialEq for GenericArray -where - N: ArrayLength, -{ - fn eq(&self, other: &Self) -> bool { - **self == **other - } -} -impl Eq for GenericArray -where - N: ArrayLength, -{ -} - -impl PartialOrd for GenericArray -where - N: ArrayLength, -{ - fn partial_cmp(&self, other: &GenericArray) -> Option { - PartialOrd::partial_cmp(self.as_slice(), other.as_slice()) - } -} - -impl Ord for GenericArray -where - N: ArrayLength, -{ - fn cmp(&self, other: &GenericArray) -> Ordering { - Ord::cmp(self.as_slice(), other.as_slice()) - } -} - -impl Debug for GenericArray -where - N: ArrayLength, -{ - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - self[..].fmt(fmt) - } -} - -impl Borrow<[T]> for GenericArray -where - N: ArrayLength, -{ - fn borrow(&self) -> &[T] { - &self[..] - } -} - -impl BorrowMut<[T]> for GenericArray -where - N: ArrayLength, -{ - fn borrow_mut(&mut self) -> &mut [T] { - &mut self[..] - } -} - -impl AsRef<[T]> for GenericArray -where - N: ArrayLength, -{ - fn as_ref(&self) -> &[T] { - &self[..] - } -} - -impl AsMut<[T]> for GenericArray -where - N: ArrayLength, -{ - fn as_mut(&mut self) -> &mut [T] { - &mut self[..] - } -} - -impl Hash for GenericArray -where - N: ArrayLength, -{ - fn hash(&self, state: &mut H) - where - H: Hasher, - { - Hash::hash(&self[..], state) - } -} - -macro_rules! impl_from { - ($($n: expr => $ty: ty),*) => { - $( - impl From<[T; $n]> for GenericArray { - fn from(arr: [T; $n]) -> Self { - use core::mem::{forget, transmute_copy}; - let x = unsafe { transmute_copy(&arr) }; - forget(arr); - x - } - } - )* - - } -} - -impl_from! { - 1 => ::typenum::U1, - 2 => ::typenum::U2, - 3 => ::typenum::U3, - 4 => ::typenum::U4, - 5 => ::typenum::U5, - 6 => ::typenum::U6, - 7 => ::typenum::U7, - 8 => ::typenum::U8, - 9 => ::typenum::U9, - 10 => ::typenum::U10, - 11 => ::typenum::U11, - 12 => ::typenum::U12, - 13 => ::typenum::U13, - 14 => ::typenum::U14, - 15 => ::typenum::U15, - 16 => ::typenum::U16, - 17 => ::typenum::U17, - 18 => ::typenum::U18, - 19 => ::typenum::U19, - 20 => ::typenum::U20, - 21 => ::typenum::U21, - 22 => ::typenum::U22, - 23 => ::typenum::U23, - 24 => ::typenum::U24, - 25 => ::typenum::U25, - 26 => ::typenum::U26, - 27 => ::typenum::U27, - 28 => ::typenum::U28, - 29 => ::typenum::U29, - 30 => ::typenum::U30, - 31 => ::typenum::U31, - 32 => ::typenum::U32 -} \ No newline at end of file +use super::{ArrayLength, GenericArray}; +use core::borrow::{Borrow, BorrowMut}; +use core::cmp::Ordering; +use core::fmt::{self, Debug}; +use core::hash::{Hash, Hasher}; +use functional::*; +use sequence::*; + +impl Default for GenericArray +where + N: ArrayLength, +{ + #[inline] + fn default() -> Self { + Self::generate(|_| T::default()) + } +} + +impl Clone for GenericArray +where + N: ArrayLength, +{ + fn clone(&self) -> GenericArray { + self.map(|x| x.clone()) + } +} + +impl Copy for GenericArray +where + N: ArrayLength, + N::ArrayType: Copy, +{ +} + +impl PartialEq for GenericArray +where + N: ArrayLength, +{ + fn eq(&self, other: &Self) -> bool { + **self == **other + } +} +impl Eq for GenericArray +where + N: ArrayLength, +{ +} + +impl PartialOrd for GenericArray +where + N: ArrayLength, +{ + fn partial_cmp(&self, other: &GenericArray) -> Option { + PartialOrd::partial_cmp(self.as_slice(), other.as_slice()) + } +} + +impl Ord for GenericArray +where + N: ArrayLength, +{ + fn cmp(&self, other: &GenericArray) -> Ordering { + Ord::cmp(self.as_slice(), other.as_slice()) + } +} + +impl Debug for GenericArray +where + N: ArrayLength, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + self[..].fmt(fmt) + } +} + +impl Borrow<[T]> for GenericArray +where + N: ArrayLength, +{ + fn borrow(&self) -> &[T] { + &self[..] + } +} + +impl BorrowMut<[T]> for GenericArray +where + N: ArrayLength, +{ + fn borrow_mut(&mut self) -> &mut [T] { + &mut self[..] + } +} + +impl AsRef<[T]> for GenericArray +where + N: ArrayLength, +{ + fn as_ref(&self) -> &[T] { + &self[..] + } +} + +impl AsMut<[T]> for GenericArray +where + N: ArrayLength, +{ + fn as_mut(&mut self) -> &mut [T] { + &mut self[..] + } +} + +impl Hash for GenericArray +where + N: ArrayLength, +{ + fn hash(&self, state: &mut H) + where + H: Hasher, + { + Hash::hash(&self[..], state) + } +} + +macro_rules! impl_from { + ($($n: expr => $ty: ty),*) => { + $( + impl From<[T; $n]> for GenericArray { + fn from(arr: [T; $n]) -> Self { + use core::mem::{forget, transmute_copy}; + let x = unsafe { transmute_copy(&arr) }; + forget(arr); + x + } + } + )* + + } +} + +impl_from! { + 1 => ::typenum::U1, + 2 => ::typenum::U2, + 3 => ::typenum::U3, + 4 => ::typenum::U4, + 5 => ::typenum::U5, + 6 => ::typenum::U6, + 7 => ::typenum::U7, + 8 => ::typenum::U8, + 9 => ::typenum::U9, + 10 => ::typenum::U10, + 11 => ::typenum::U11, + 12 => ::typenum::U12, + 13 => ::typenum::U13, + 14 => ::typenum::U14, + 15 => ::typenum::U15, + 16 => ::typenum::U16, + 17 => ::typenum::U17, + 18 => ::typenum::U18, + 19 => ::typenum::U19, + 20 => ::typenum::U20, + 21 => ::typenum::U21, + 22 => ::typenum::U22, + 23 => ::typenum::U23, + 24 => ::typenum::U24, + 25 => ::typenum::U25, + 26 => ::typenum::U26, + 27 => ::typenum::U27, + 28 => ::typenum::U28, + 29 => ::typenum::U29, + 30 => ::typenum::U30, + 31 => ::typenum::U31, + 32 => ::typenum::U32 +} diff --git a/third_party/rust/generic-array/src/iter.rs b/third_party/rust/generic-array/src/iter.rs index b9282761a45f..46f3e768d711 100644 --- a/third_party/rust/generic-array/src/iter.rs +++ b/third_party/rust/generic-array/src/iter.rs @@ -1,117 +1,190 @@ -//! `GenericArray` iterator implementation. - -use super::{ArrayLength, GenericArray}; -use core::{cmp, ptr}; -use core::mem::ManuallyDrop; - -/// An iterator that moves out of a `GenericArray` -pub struct GenericArrayIter> { - // Invariants: index <= index_back <= N - // Only values in array[index..index_back] are alive at any given time. - // Values from array[..index] and array[index_back..] are already moved/dropped. - array: ManuallyDrop>, - index: usize, - index_back: usize, -} - -impl IntoIterator for GenericArray -where - N: ArrayLength, -{ - type Item = T; - type IntoIter = GenericArrayIter; - - fn into_iter(self) -> Self::IntoIter { - GenericArrayIter { - array: ManuallyDrop::new(self), - index: 0, - index_back: N::to_usize(), - } - } -} - -impl Drop for GenericArrayIter -where - N: ArrayLength, -{ - fn drop(&mut self) { - // Drop values that are still alive. - for p in &mut self.array[self.index..self.index_back] { - unsafe { - ptr::drop_in_place(p); - } - } - } -} - -impl Iterator for GenericArrayIter -where - N: ArrayLength, -{ - type Item = T; - - fn next(&mut self) -> Option { - if self.len() > 0 { - unsafe { - let p = self.array.get_unchecked(self.index); - self.index += 1; - Some(ptr::read(p)) - } - } else { - None - } - } - - fn size_hint(&self) -> (usize, Option) { - let len = self.len(); - (len, Some(len)) - } - - fn count(self) -> usize { - self.len() - } - - fn nth(&mut self, n: usize) -> Option { - // First consume values prior to the nth. - let ndrop = cmp::min(n, self.len()); - for p in &mut self.array[self.index..self.index + ndrop] { - self.index += 1; - unsafe { - ptr::drop_in_place(p); - } - } - - self.next() - } - - fn last(mut self) -> Option { - // Note, everything else will correctly drop first as `self` leaves scope. - self.next_back() - } -} - -impl DoubleEndedIterator for GenericArrayIter -where - N: ArrayLength, -{ - fn next_back(&mut self) -> Option { - if self.len() > 0 { - self.index_back -= 1; - unsafe { - let p = self.array.get_unchecked(self.index_back); - Some(ptr::read(p)) - } - } else { - None - } - } -} - -impl ExactSizeIterator for GenericArrayIter -where - N: ArrayLength, -{ - fn len(&self) -> usize { - self.index_back - self.index - } -} +//! `GenericArray` iterator implementation. + +use super::{ArrayLength, GenericArray}; +use core::{cmp, ptr, fmt, mem}; +use core::mem::ManuallyDrop; + +/// An iterator that moves out of a `GenericArray` +pub struct GenericArrayIter> { + // Invariants: index <= index_back <= N + // Only values in array[index..index_back] are alive at any given time. + // Values from array[..index] and array[index_back..] are already moved/dropped. + array: ManuallyDrop>, + index: usize, + index_back: usize, +} + +#[cfg(test)] +mod test { + use super::*; + + fn send(_iter: I) {} + + #[test] + fn test_send_iter() { + send(GenericArray::from([1, 2, 3, 4]).into_iter()); + } +} + +impl GenericArrayIter +where + N: ArrayLength, +{ + /// Returns the remaining items of this iterator as a slice + #[inline] + pub fn as_slice(&self) -> &[T] { + &self.array.as_slice()[self.index..self.index_back] + } + + /// Returns the remaining items of this iterator as a mutable slice + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [T] { + &mut self.array.as_mut_slice()[self.index..self.index_back] + } +} + +impl IntoIterator for GenericArray +where + N: ArrayLength, +{ + type Item = T; + type IntoIter = GenericArrayIter; + + fn into_iter(self) -> Self::IntoIter { + GenericArrayIter { + array: ManuallyDrop::new(self), + index: 0, + index_back: N::to_usize(), + } + } +} + +// Based on work in rust-lang/rust#49000 +impl fmt::Debug for GenericArrayIter +where + N: ArrayLength, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("GenericArrayIter") + .field(&self.as_slice()) + .finish() + } +} + +impl Drop for GenericArrayIter +where + N: ArrayLength, +{ + #[inline] + fn drop(&mut self) { + // Drop values that are still alive. + for p in self.as_mut_slice() { + unsafe { + ptr::drop_in_place(p); + } + } + } +} + +// Based on work in rust-lang/rust#49000 +impl Clone for GenericArrayIter +where + N: ArrayLength, +{ + fn clone(&self) -> Self { + // This places all cloned elements at the start of the new array iterator, + // not at their original indices. + unsafe { + let mut iter = GenericArrayIter { + array: ManuallyDrop::new(mem::uninitialized()), + index: 0, + index_back: 0, + }; + + for (dst, src) in iter.array.iter_mut().zip(self.as_slice()) { + ptr::write(dst, src.clone()); + + iter.index_back += 1; + } + + iter + } + } +} + +impl Iterator for GenericArrayIter +where + N: ArrayLength, +{ + type Item = T; + + #[inline] + fn next(&mut self) -> Option { + if self.index < self.index_back { + let p = unsafe { Some(ptr::read(self.array.get_unchecked(self.index))) }; + + self.index += 1; + + p + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.len(); + (len, Some(len)) + } + + #[inline] + fn count(self) -> usize { + self.len() + } + + fn nth(&mut self, n: usize) -> Option { + // First consume values prior to the nth. + let ndrop = cmp::min(n, self.len()); + + for p in &mut self.array[self.index..self.index + ndrop] { + self.index += 1; + + unsafe { + ptr::drop_in_place(p); + } + } + + self.next() + } + + fn last(mut self) -> Option { + // Note, everything else will correctly drop first as `self` leaves scope. + self.next_back() + } +} + +impl DoubleEndedIterator for GenericArrayIter +where + N: ArrayLength, +{ + fn next_back(&mut self) -> Option { + if self.index < self.index_back { + self.index_back -= 1; + + unsafe { Some(ptr::read(self.array.get_unchecked(self.index_back))) } + } else { + None + } + } +} + +impl ExactSizeIterator for GenericArrayIter +where + N: ArrayLength, +{ + fn len(&self) -> usize { + self.index_back - self.index + } +} + +// TODO: Implement `FusedIterator` and `TrustedLen` when stabilized \ No newline at end of file diff --git a/third_party/rust/generic-array/src/lib.rs b/third_party/rust/generic-array/src/lib.rs index ce478e5ec690..d07b46277852 100644 --- a/third_party/rust/generic-array/src/lib.rs +++ b/third_party/rust/generic-array/src/lib.rs @@ -1,464 +1,630 @@ -//! This crate implements a structure that can be used as a generic array type.use -//! Core Rust array types `[T; N]` can't be used generically with -//! respect to `N`, so for example this: -//! -//! ```{should_fail} -//! struct Foo { -//! data: [T; N] -//! } -//! ``` -//! -//! won't work. -//! -//! **generic-array** exports a `GenericArray` type, which lets -//! the above be implemented as: -//! -//! ``` -//! # use generic_array::{ArrayLength, GenericArray}; -//! struct Foo> { -//! data: GenericArray -//! } -//! ``` -//! -//! The `ArrayLength` trait is implemented by default for -//! [unsigned integer types](../typenum/uint/index.html) from -//! [typenum](../typenum/index.html). -//! -//! For ease of use, an `arr!` macro is provided - example below: -//! -//! ``` -//! # #[macro_use] -//! # extern crate generic_array; -//! # extern crate typenum; -//! # fn main() { -//! let array = arr![u32; 1, 2, 3]; -//! assert_eq!(array[2], 3); -//! # } -//! ``` - -//#![deny(missing_docs)] -#![no_std] - -pub extern crate typenum; -#[cfg(feature = "serde")] -extern crate serde; - -mod hex; -mod impls; - -#[cfg(feature = "serde")] -pub mod impl_serde; - -use core::{mem, ptr, slice}; - -use core::marker::PhantomData; -use core::mem::ManuallyDrop; -pub use core::mem::transmute; -use core::ops::{Deref, DerefMut}; - -use typenum::bit::{B0, B1}; -use typenum::uint::{UInt, UTerm, Unsigned}; - -#[cfg_attr(test, macro_use)] -pub mod arr; -pub mod iter; -pub use iter::GenericArrayIter; - -/// Trait making `GenericArray` work, marking types to be used as length of an array -pub unsafe trait ArrayLength: Unsigned { - /// Associated type representing the array type for the number - type ArrayType; -} - -unsafe impl ArrayLength for UTerm { - #[doc(hidden)] - type ArrayType = (); -} - -/// Internal type used to generate a struct of appropriate size -#[allow(dead_code)] -#[repr(C)] -#[doc(hidden)] -pub struct GenericArrayImplEven { - parent1: U, - parent2: U, - _marker: PhantomData, -} - -impl Clone for GenericArrayImplEven { - fn clone(&self) -> GenericArrayImplEven { - GenericArrayImplEven { - parent1: self.parent1.clone(), - parent2: self.parent2.clone(), - _marker: PhantomData, - } - } -} - -impl Copy for GenericArrayImplEven {} - -/// Internal type used to generate a struct of appropriate size -#[allow(dead_code)] -#[repr(C)] -#[doc(hidden)] -pub struct GenericArrayImplOdd { - parent1: U, - parent2: U, - data: T, -} - -impl Clone for GenericArrayImplOdd { - fn clone(&self) -> GenericArrayImplOdd { - GenericArrayImplOdd { - parent1: self.parent1.clone(), - parent2: self.parent2.clone(), - data: self.data.clone(), - } - } -} - -impl Copy for GenericArrayImplOdd {} - -unsafe impl> ArrayLength for UInt { - #[doc(hidden)] - type ArrayType = GenericArrayImplEven; -} - -unsafe impl> ArrayLength for UInt { - #[doc(hidden)] - type ArrayType = GenericArrayImplOdd; -} - -/// Struct representing a generic array - `GenericArray` works like [T; N] -#[allow(dead_code)] -pub struct GenericArray> { - data: U::ArrayType, -} - -impl Deref for GenericArray -where - N: ArrayLength, -{ - type Target = [T]; - - fn deref(&self) -> &[T] { - unsafe { slice::from_raw_parts(self as *const Self as *const T, N::to_usize()) } - } -} - -impl DerefMut for GenericArray -where - N: ArrayLength, -{ - fn deref_mut(&mut self) -> &mut [T] { - unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize()) } - } -} - -struct ArrayBuilder> { - array: ManuallyDrop>, - position: usize, -} - -impl> ArrayBuilder { - fn new() -> ArrayBuilder { - ArrayBuilder { - array: ManuallyDrop::new(unsafe { mem::uninitialized() }), - position: 0, - } - } - - fn into_inner(self) -> GenericArray { - let array = unsafe { ptr::read(&self.array) }; - - mem::forget(self); - - ManuallyDrop::into_inner(array) - } -} - -impl> Drop for ArrayBuilder { - fn drop(&mut self) { - for value in self.array.iter_mut().take(self.position) { - unsafe { - ptr::drop_in_place(value); - } - } - } -} - -struct ArrayConsumer> { - array: ManuallyDrop>, - position: usize, -} - -impl> ArrayConsumer { - fn new(array: GenericArray) -> ArrayConsumer { - ArrayConsumer { - array: ManuallyDrop::new(array), - position: 0, - } - } -} - -impl> Drop for ArrayConsumer { - fn drop(&mut self) { - for i in self.position..N::to_usize() { - unsafe { - ptr::drop_in_place(self.array.get_unchecked_mut(i)); - } - } - } -} - -impl GenericArray -where - N: ArrayLength, -{ - /// Initializes a new `GenericArray` instance using the given function. - /// - /// If the generator function panics while initializing the array, - /// any already initialized elements will be dropped. - pub fn generate(f: F) -> GenericArray - where - F: Fn(usize) -> T, - { - let mut destination = ArrayBuilder::new(); - - for (i, dst) in destination.array.iter_mut().enumerate() { - unsafe { - ptr::write(dst, f(i)); - } - - destination.position += 1; - } - - destination.into_inner() - } - - /// Map a function over a slice to a `GenericArray`. - /// - /// The length of the slice *must* be equal to the length of the array. - #[inline] - pub fn map_slice T>(s: &[S], f: F) -> GenericArray { - assert_eq!(s.len(), N::to_usize()); - - Self::generate(|i| f(unsafe { s.get_unchecked(i) })) - } - - /// Maps a `GenericArray` to another `GenericArray`. - /// - /// If the mapping function panics, any already initialized elements in the new array - /// will be dropped, AND any unused elements in the source array will also be dropped. - pub fn map(self, f: F) -> GenericArray - where - F: Fn(T) -> U, - N: ArrayLength, - { - let mut source = ArrayConsumer::new(self); - let mut destination = ArrayBuilder::new(); - - for (dst, src) in destination.array.iter_mut().zip(source.array.iter()) { - unsafe { - ptr::write(dst, f(ptr::read(src))); - } - - source.position += 1; - destination.position += 1; - } - - destination.into_inner() - } - - /// Maps a `GenericArray` to another `GenericArray` by reference. - /// - /// If the mapping function panics, any already initialized elements will be dropped. - #[inline] - pub fn map_ref(&self, f: F) -> GenericArray - where - F: Fn(&T) -> U, - N: ArrayLength, - { - GenericArray::generate(|i| f(unsafe { self.get_unchecked(i) })) - } - - /// Combines two `GenericArray` instances and iterates through both of them, - /// initializing a new `GenericArray` with the result of the zipped mapping function. - /// - /// If the mapping function panics, any already initialized elements in the new array - /// will be dropped, AND any unused elements in the source arrays will also be dropped. - pub fn zip(self, rhs: GenericArray, f: F) -> GenericArray - where - F: Fn(T, B) -> U, - N: ArrayLength + ArrayLength, - { - let mut left = ArrayConsumer::new(self); - let mut right = ArrayConsumer::new(rhs); - - let mut destination = ArrayBuilder::new(); - - for (dst, (lhs, rhs)) in - destination.array.iter_mut().zip(left.array.iter().zip( - right.array.iter(), - )) - { - unsafe { - ptr::write(dst, f(ptr::read(lhs), ptr::read(rhs))); - } - - destination.position += 1; - left.position += 1; - right.position += 1; - } - - destination.into_inner() - } - - /// Combines two `GenericArray` instances and iterates through both of them by reference, - /// initializing a new `GenericArray` with the result of the zipped mapping function. - /// - /// If the mapping function panics, any already initialized elements will be dropped. - pub fn zip_ref(&self, rhs: &GenericArray, f: F) -> GenericArray - where - F: Fn(&T, &B) -> U, - N: ArrayLength + ArrayLength, - { - GenericArray::generate(|i| unsafe { - f(self.get_unchecked(i), rhs.get_unchecked(i)) - }) - } - - /// Extracts a slice containing the entire array. - #[inline] - pub fn as_slice(&self) -> &[T] { - self.deref() - } - - /// Extracts a mutable slice containing the entire array. - #[inline] - pub fn as_mut_slice(&mut self) -> &mut [T] { - self.deref_mut() - } - - /// Converts slice to a generic array reference with inferred length; - /// - /// Length of the slice must be equal to the length of the array. - #[inline] - pub fn from_slice(slice: &[T]) -> &GenericArray { - assert_eq!(slice.len(), N::to_usize()); - - unsafe { &*(slice.as_ptr() as *const GenericArray) } - } - - /// Converts mutable slice to a mutable generic array reference - /// - /// Length of the slice must be equal to the length of the array. - #[inline] - pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray { - assert_eq!(slice.len(), N::to_usize()); - - unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray) } - } -} - -impl GenericArray -where - N: ArrayLength, -{ - /// Construct a `GenericArray` from a slice by cloning its content - /// - /// Length of the slice must be equal to the length of the array - #[inline] - pub fn clone_from_slice(list: &[T]) -> GenericArray { - Self::from_exact_iter(list.iter().cloned()).expect( - "Slice must be the same length as the array", - ) - } -} - -impl GenericArray -where - N: ArrayLength, -{ - pub fn from_exact_iter(iter: I) -> Option - where - I: IntoIterator, - ::IntoIter: ExactSizeIterator, - { - let iter = iter.into_iter(); - - if iter.len() == N::to_usize() { - let mut destination = ArrayBuilder::new(); - - for (dst, src) in destination.array.iter_mut().zip(iter.into_iter()) { - unsafe { - ptr::write(dst, src); - } - - destination.position += 1; - } - - let array = unsafe { ptr::read(&destination.array) }; - - mem::forget(destination); - - Some(ManuallyDrop::into_inner(array)) - } else { - None - } - } -} - -impl ::core::iter::FromIterator for GenericArray -where - N: ArrayLength, - T: Default, -{ - fn from_iter(iter: I) -> GenericArray - where - I: IntoIterator, - { - let mut destination = ArrayBuilder::new(); - - let defaults = ::core::iter::repeat(()).map(|_| T::default()); - - for (dst, src) in destination.array.iter_mut().zip( - iter.into_iter().chain(defaults), - ) - { - unsafe { - ptr::write(dst, src); - } - } - - destination.into_inner() - } -} - -#[cfg(test)] -mod test { - // Compile with: - // cargo rustc --lib --profile test --release -- - // -C target-cpu=native -C opt-level=3 --emit asm - // and view the assembly to make sure test_assembly generates - // SIMD instructions instead of a niave loop. - - #[inline(never)] - pub fn black_box(val: T) -> T { - use core::{mem, ptr}; - - let ret = unsafe { ptr::read_volatile(&val) }; - mem::forget(val); - ret - } - - #[test] - fn test_assembly() { - let a = black_box(arr![i32; 1, 3, 5, 7]); - let b = black_box(arr![i32; 2, 4, 6, 8]); - - let c = a.zip_ref(&b, |l, r| l + r); - - assert_eq!(c, arr![i32; 3, 7, 11, 15]); - } -} +//! This crate implements a structure that can be used as a generic array type.use +//! Core Rust array types `[T; N]` can't be used generically with +//! respect to `N`, so for example this: +//! +//! ```{should_fail} +//! struct Foo { +//! data: [T; N] +//! } +//! ``` +//! +//! won't work. +//! +//! **generic-array** exports a `GenericArray` type, which lets +//! the above be implemented as: +//! +//! ``` +//! # use generic_array::{ArrayLength, GenericArray}; +//! struct Foo> { +//! data: GenericArray +//! } +//! ``` +//! +//! The `ArrayLength` trait is implemented by default for +//! [unsigned integer types](../typenum/uint/index.html) from +//! [typenum](../typenum/index.html). +//! +//! For ease of use, an `arr!` macro is provided - example below: +//! +//! ``` +//! # #[macro_use] +//! # extern crate generic_array; +//! # extern crate typenum; +//! # fn main() { +//! let array = arr![u32; 1, 2, 3]; +//! assert_eq!(array[2], 3); +//! # } +//! ``` + +#![deny(missing_docs)] +#![no_std] + +#[cfg(feature = "serde")] +extern crate serde; + +#[cfg(test)] +extern crate bincode; + +pub extern crate typenum; + +mod hex; +mod impls; + +#[cfg(feature = "serde")] +pub mod impl_serde; + +use core::iter::FromIterator; +use core::marker::PhantomData; +use core::mem::ManuallyDrop; +use core::ops::{Deref, DerefMut}; +use core::{mem, ptr, slice}; +use typenum::bit::{B0, B1}; +use typenum::uint::{UInt, UTerm, Unsigned}; + +#[cfg_attr(test, macro_use)] +pub mod arr; +pub mod functional; +pub mod iter; +pub mod sequence; + +use functional::*; +pub use iter::GenericArrayIter; +use sequence::*; + +/// Trait making `GenericArray` work, marking types to be used as length of an array +pub unsafe trait ArrayLength: Unsigned { + /// Associated type representing the array type for the number + type ArrayType; +} + +unsafe impl ArrayLength for UTerm { + #[doc(hidden)] + type ArrayType = (); +} + +/// Internal type used to generate a struct of appropriate size +#[allow(dead_code)] +#[repr(C)] +#[doc(hidden)] +pub struct GenericArrayImplEven { + parent1: U, + parent2: U, + _marker: PhantomData, +} + +impl Clone for GenericArrayImplEven { + fn clone(&self) -> GenericArrayImplEven { + GenericArrayImplEven { + parent1: self.parent1.clone(), + parent2: self.parent2.clone(), + _marker: PhantomData, + } + } +} + +impl Copy for GenericArrayImplEven {} + +/// Internal type used to generate a struct of appropriate size +#[allow(dead_code)] +#[repr(C)] +#[doc(hidden)] +pub struct GenericArrayImplOdd { + parent1: U, + parent2: U, + data: T, +} + +impl Clone for GenericArrayImplOdd { + fn clone(&self) -> GenericArrayImplOdd { + GenericArrayImplOdd { + parent1: self.parent1.clone(), + parent2: self.parent2.clone(), + data: self.data.clone(), + } + } +} + +impl Copy for GenericArrayImplOdd {} + +unsafe impl> ArrayLength for UInt { + #[doc(hidden)] + type ArrayType = GenericArrayImplEven; +} + +unsafe impl> ArrayLength for UInt { + #[doc(hidden)] + type ArrayType = GenericArrayImplOdd; +} + +/// Struct representing a generic array - `GenericArray` works like [T; N] +#[allow(dead_code)] +pub struct GenericArray> { + data: U::ArrayType, +} + +unsafe impl> Send for GenericArray {} +unsafe impl> Sync for GenericArray {} + +impl Deref for GenericArray +where + N: ArrayLength, +{ + type Target = [T]; + + fn deref(&self) -> &[T] { + unsafe { slice::from_raw_parts(self as *const Self as *const T, N::to_usize()) } + } +} + +impl DerefMut for GenericArray +where + N: ArrayLength, +{ + fn deref_mut(&mut self) -> &mut [T] { + unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize()) } + } +} + +/// Creates an array one element at a time using a mutable iterator +/// you can write to with `ptr::write`. +/// +/// Incremenent the position while iterating to mark off created elements, +/// which will be dropped if `into_inner` is not called. +#[doc(hidden)] +pub struct ArrayBuilder> { + array: ManuallyDrop>, + position: usize, +} + +impl> ArrayBuilder { + #[doc(hidden)] + #[inline] + pub unsafe fn new() -> ArrayBuilder { + ArrayBuilder { + array: ManuallyDrop::new(mem::uninitialized()), + position: 0, + } + } + + /// Creates a mutable iterator for writing to the array using `ptr::write`. + /// + /// Increment the position value given as a mutable reference as you iterate + /// to mark how many elements have been created. + #[doc(hidden)] + #[inline] + pub unsafe fn iter_position(&mut self) -> (slice::IterMut, &mut usize) { + (self.array.iter_mut(), &mut self.position) + } + + /// When done writing (assuming all elements have been written to), + /// get the inner array. + #[doc(hidden)] + #[inline] + pub unsafe fn into_inner(self) -> GenericArray { + let array = ptr::read(&self.array); + + mem::forget(self); + + ManuallyDrop::into_inner(array) + } +} + +impl> Drop for ArrayBuilder { + fn drop(&mut self) { + for value in &mut self.array[..self.position] { + unsafe { + ptr::drop_in_place(value); + } + } + } +} + +/// Consumes an array. +/// +/// Increment the position while iterating and any leftover elements +/// will be dropped if position does not go to N +#[doc(hidden)] +pub struct ArrayConsumer> { + array: ManuallyDrop>, + position: usize, +} + +impl> ArrayConsumer { + #[doc(hidden)] + #[inline] + pub unsafe fn new(array: GenericArray) -> ArrayConsumer { + ArrayConsumer { + array: ManuallyDrop::new(array), + position: 0, + } + } + + /// Creates an iterator and mutable reference to the internal position + /// to keep track of consumed elements. + /// + /// Increment the position as you iterate to mark off consumed elements + #[doc(hidden)] + #[inline] + pub unsafe fn iter_position(&mut self) -> (slice::Iter, &mut usize) { + (self.array.iter(), &mut self.position) + } +} + +impl> Drop for ArrayConsumer { + fn drop(&mut self) { + for value in &mut self.array[self.position..N::to_usize()] { + unsafe { + ptr::drop_in_place(value); + } + } + } +} + +impl<'a, T: 'a, N> IntoIterator for &'a GenericArray +where + N: ArrayLength, +{ + type IntoIter = slice::Iter<'a, T>; + type Item = &'a T; + + fn into_iter(self: &'a GenericArray) -> Self::IntoIter { + self.as_slice().iter() + } +} + +impl<'a, T: 'a, N> IntoIterator for &'a mut GenericArray +where + N: ArrayLength, +{ + type IntoIter = slice::IterMut<'a, T>; + type Item = &'a mut T; + + fn into_iter(self: &'a mut GenericArray) -> Self::IntoIter { + self.as_mut_slice().iter_mut() + } +} + +impl FromIterator for GenericArray +where + N: ArrayLength, +{ + fn from_iter(iter: I) -> GenericArray + where + I: IntoIterator, + { + unsafe { + let mut destination = ArrayBuilder::new(); + + { + let (destination_iter, position) = destination.iter_position(); + + for (src, dst) in iter.into_iter().zip(destination_iter) { + ptr::write(dst, src); + + *position += 1; + } + } + + if destination.position < N::to_usize() { + from_iter_length_fail(destination.position, N::to_usize()); + } + + destination.into_inner() + } + } +} + +#[inline(never)] +#[cold] +fn from_iter_length_fail(length: usize, expected: usize) -> ! { + panic!( + "GenericArray::from_iter received {} elements but expected {}", + length, expected + ); +} + +unsafe impl GenericSequence for GenericArray +where + N: ArrayLength, + Self: IntoIterator, +{ + type Length = N; + type Sequence = Self; + + fn generate(mut f: F) -> GenericArray + where + F: FnMut(usize) -> T, + { + unsafe { + let mut destination = ArrayBuilder::new(); + + { + let (destination_iter, position) = destination.iter_position(); + + for (i, dst) in destination_iter.enumerate() { + ptr::write(dst, f(i)); + + *position += 1; + } + } + + destination.into_inner() + } + } + + #[doc(hidden)] + fn inverted_zip( + self, + lhs: GenericArray, + mut f: F, + ) -> MappedSequence, B, U> + where + GenericArray: + GenericSequence + MappedGenericSequence, + Self: MappedGenericSequence, + Self::Length: ArrayLength + ArrayLength, + F: FnMut(B, Self::Item) -> U, + { + unsafe { + let mut left = ArrayConsumer::new(lhs); + let mut right = ArrayConsumer::new(self); + + let (left_array_iter, left_position) = left.iter_position(); + let (right_array_iter, right_position) = right.iter_position(); + + FromIterator::from_iter(left_array_iter.zip(right_array_iter).map(|(l, r)| { + let left_value = ptr::read(l); + let right_value = ptr::read(r); + + *left_position += 1; + *right_position += 1; + + f(left_value, right_value) + })) + } + } + + #[doc(hidden)] + fn inverted_zip2(self, lhs: Lhs, mut f: F) -> MappedSequence + where + Lhs: GenericSequence + MappedGenericSequence, + Self: MappedGenericSequence, + Self::Length: ArrayLength + ArrayLength, + F: FnMut(Lhs::Item, Self::Item) -> U, + { + unsafe { + let mut right = ArrayConsumer::new(self); + + let (right_array_iter, right_position) = right.iter_position(); + + FromIterator::from_iter( + lhs.into_iter() + .zip(right_array_iter) + .map(|(left_value, r)| { + let right_value = ptr::read(r); + + *right_position += 1; + + f(left_value, right_value) + }), + ) + } + } +} + +unsafe impl MappedGenericSequence for GenericArray +where + N: ArrayLength + ArrayLength, + GenericArray: GenericSequence, +{ + type Mapped = GenericArray; +} + +unsafe impl FunctionalSequence for GenericArray +where + N: ArrayLength, + Self: GenericSequence, +{ + fn map(self, mut f: F) -> MappedSequence + where + Self::Length: ArrayLength, + Self: MappedGenericSequence, + F: FnMut(T) -> U, + { + unsafe { + let mut source = ArrayConsumer::new(self); + + let (array_iter, position) = source.iter_position(); + + FromIterator::from_iter(array_iter.map(|src| { + let value = ptr::read(src); + + *position += 1; + + f(value) + })) + } + } + + #[inline] + fn zip(self, rhs: Rhs, f: F) -> MappedSequence + where + Self: MappedGenericSequence, + Rhs: MappedGenericSequence>, + Self::Length: ArrayLength + ArrayLength, + Rhs: GenericSequence, + F: FnMut(T, Rhs::Item) -> U, + { + rhs.inverted_zip(self, f) + } + + fn fold(self, init: U, mut f: F) -> U + where + F: FnMut(U, T) -> U, + { + unsafe { + let mut source = ArrayConsumer::new(self); + + let (array_iter, position) = source.iter_position(); + + array_iter.fold(init, |acc, src| { + let value = ptr::read(src); + + *position += 1; + + f(acc, value) + }) + } + } +} + +impl GenericArray +where + N: ArrayLength, +{ + /// Extracts a slice containing the entire array. + #[inline] + pub fn as_slice(&self) -> &[T] { + self.deref() + } + + /// Extracts a mutable slice containing the entire array. + #[inline] + pub fn as_mut_slice(&mut self) -> &mut [T] { + self.deref_mut() + } + + /// Converts slice to a generic array reference with inferred length; + /// + /// Length of the slice must be equal to the length of the array. + #[inline] + pub fn from_slice(slice: &[T]) -> &GenericArray { + slice.into() + } + + /// Converts mutable slice to a mutable generic array reference + /// + /// Length of the slice must be equal to the length of the array. + #[inline] + pub fn from_mut_slice(slice: &mut [T]) -> &mut GenericArray { + slice.into() + } +} + +impl<'a, T, N: ArrayLength> From<&'a [T]> for &'a GenericArray { + /// Converts slice to a generic array reference with inferred length; + /// + /// Length of the slice must be equal to the length of the array. + #[inline] + fn from(slice: &[T]) -> &GenericArray { + assert_eq!(slice.len(), N::to_usize()); + + unsafe { &*(slice.as_ptr() as *const GenericArray) } + } +} + +impl<'a, T, N: ArrayLength> From<&'a mut [T]> for &'a mut GenericArray { + /// Converts mutable slice to a mutable generic array reference + /// + /// Length of the slice must be equal to the length of the array. + #[inline] + fn from(slice: &mut [T]) -> &mut GenericArray { + assert_eq!(slice.len(), N::to_usize()); + + unsafe { &mut *(slice.as_mut_ptr() as *mut GenericArray) } + } +} + +impl GenericArray +where + N: ArrayLength, +{ + /// Construct a `GenericArray` from a slice by cloning its content + /// + /// Length of the slice must be equal to the length of the array + #[inline] + pub fn clone_from_slice(list: &[T]) -> GenericArray { + Self::from_exact_iter(list.iter().cloned()) + .expect("Slice must be the same length as the array") + } +} + +impl GenericArray +where + N: ArrayLength, +{ + /// Creates a new `GenericArray` instance from an iterator with a known exact size. + /// + /// Returns `None` if the size is not equal to the number of elements in the `GenericArray`. + pub fn from_exact_iter(iter: I) -> Option + where + I: IntoIterator, + ::IntoIter: ExactSizeIterator, + { + let iter = iter.into_iter(); + + if iter.len() == N::to_usize() { + unsafe { + let mut destination = ArrayBuilder::new(); + + { + let (destination_iter, position) = destination.iter_position(); + + for (dst, src) in destination_iter.zip(iter.into_iter()) { + ptr::write(dst, src); + + *position += 1; + } + } + + Some(destination.into_inner()) + } + } else { + None + } + } +} + +/// A reimplementation of the `transmute` function, avoiding problems +/// when the compiler can't prove equal sizes. +#[inline] +#[doc(hidden)] +pub unsafe fn transmute(a: A) -> B { + let b = ::core::ptr::read(&a as *const A as *const B); + ::core::mem::forget(a); + b +} + +#[cfg(test)] +mod test { + // Compile with: + // cargo rustc --lib --profile test --release -- + // -C target-cpu=native -C opt-level=3 --emit asm + // and view the assembly to make sure test_assembly generates + // SIMD instructions instead of a niave loop. + + #[inline(never)] + pub fn black_box(val: T) -> T { + use core::{mem, ptr}; + + let ret = unsafe { ptr::read_volatile(&val) }; + mem::forget(val); + ret + } + + #[test] + fn test_assembly() { + use functional::*; + + let a = black_box(arr![i32; 1, 3, 5, 7]); + let b = black_box(arr![i32; 2, 4, 6, 8]); + + let c = (&a).zip(b, |l, r| l + r); + + let d = a.fold(0, |a, x| a + x); + + assert_eq!(c, arr![i32; 3, 7, 11, 15]); + + assert_eq!(d, 16); + } +} diff --git a/third_party/rust/generic-array/src/sequence.rs b/third_party/rust/generic-array/src/sequence.rs new file mode 100644 index 000000000000..cec6601ba366 --- /dev/null +++ b/third_party/rust/generic-array/src/sequence.rs @@ -0,0 +1,320 @@ +//! Useful traits for manipulating sequences of data stored in `GenericArray`s + +use super::*; +use core::{mem, ptr}; +use core::ops::{Add, Sub}; +use typenum::operator_aliases::*; + +/// Defines some sequence with an associated length and iteration capabilities. +/// +/// This is useful for passing N-length generic arrays as generics. +pub unsafe trait GenericSequence: Sized + IntoIterator { + /// `GenericArray` associated length + type Length: ArrayLength; + + /// Concrete sequence type used in conjuction with reference implementations of `GenericSequence` + type Sequence: GenericSequence + FromIterator; + + /// Initializes a new sequence instance using the given function. + /// + /// If the generator function panics while initializing the sequence, + /// any already initialized elements will be dropped. + fn generate(f: F) -> Self::Sequence + where + F: FnMut(usize) -> T; + + #[doc(hidden)] + fn inverted_zip( + self, + lhs: GenericArray, + mut f: F, + ) -> MappedSequence, B, U> + where + GenericArray: GenericSequence + + MappedGenericSequence, + Self: MappedGenericSequence, + Self::Length: ArrayLength + ArrayLength, + F: FnMut(B, Self::Item) -> U, + { + unsafe { + let mut left = ArrayConsumer::new(lhs); + + let (left_array_iter, left_position) = left.iter_position(); + + FromIterator::from_iter( + left_array_iter + .zip(self.into_iter()) + .map(|(l, right_value)| { + let left_value = ptr::read(l); + + *left_position += 1; + + f(left_value, right_value) + }) + ) + } + } + + #[doc(hidden)] + fn inverted_zip2(self, lhs: Lhs, mut f: F) -> MappedSequence + where + Lhs: GenericSequence + MappedGenericSequence, + Self: MappedGenericSequence, + Self::Length: ArrayLength + ArrayLength, + F: FnMut(Lhs::Item, Self::Item) -> U, + { + FromIterator::from_iter(lhs.into_iter().zip(self.into_iter()).map(|(l, r)| f(l, r))) + } +} + +/// Accessor for `GenericSequence` item type, which is really `IntoIterator::Item` +/// +/// For deeply nested generic mapped sequence types, like shown in `tests/generics.rs`, +/// this can be useful for keeping things organized. +pub type SequenceItem = ::Item; + +unsafe impl<'a, T: 'a, S: GenericSequence> GenericSequence for &'a S +where + &'a S: IntoIterator, +{ + type Length = S::Length; + type Sequence = S::Sequence; + + #[inline] + fn generate(f: F) -> Self::Sequence + where + F: FnMut(usize) -> T, + { + S::generate(f) + } +} + +unsafe impl<'a, T: 'a, S: GenericSequence> GenericSequence for &'a mut S +where + &'a mut S: IntoIterator, +{ + type Length = S::Length; + type Sequence = S::Sequence; + + #[inline] + fn generate(f: F) -> Self::Sequence + where + F: FnMut(usize) -> T, + { + S::generate(f) + } +} + +/// Defines any `GenericSequence` which can be lengthened or extended by appending +/// or prepending an element to it. +/// +/// Any lengthened sequence can be shortened back to the original using `pop_front` or `pop_back` +pub unsafe trait Lengthen: Sized + GenericSequence { + /// `GenericSequence` that has one more element than `Self` + type Longer: Shorten; + + /// Returns a new array with the given element appended to the end of it. + /// + /// Example: + /// + /// ```ignore + /// let a = arr![i32; 1, 2, 3]; + /// + /// let b = a.append(4); + /// + /// assert_eq!(b, arr![i32; 1, 2, 3, 4]); + /// ``` + fn append(self, last: T) -> Self::Longer; + + /// Returns a new array with the given element prepended to the front of it. + /// + /// Example: + /// + /// ```ignore + /// let a = arr![i32; 1, 2, 3]; + /// + /// let b = a.prepend(4); + /// + /// assert_eq!(b, arr![i32; 4, 1, 2, 3]); + /// ``` + fn prepend(self, first: T) -> Self::Longer; +} + +/// Defines a `GenericSequence` which can be shortened by removing the first or last element from it. +/// +/// Additionally, any shortened sequence can be lengthened by +/// appending or prepending an element to it. +pub unsafe trait Shorten: Sized + GenericSequence { + /// `GenericSequence` that has one less element than `Self` + type Shorter: Lengthen; + + /// Returns a new array without the last element, and the last element. + /// + /// Example: + /// + /// ```ignore + /// let a = arr![i32; 1, 2, 3, 4]; + /// + /// let (init, last) = a.pop_back(); + /// + /// assert_eq!(init, arr![i32; 1, 2, 3]); + /// assert_eq!(last, 4); + /// ``` + fn pop_back(self) -> (Self::Shorter, T); + + /// Returns a new array without the first element, and the first element. + /// Example: + /// + /// ```ignore + /// let a = arr![i32; 1, 2, 3, 4]; + /// + /// let (head, tail) = a.pop_front(); + /// + /// assert_eq!(head, 1); + /// assert_eq!(tail, arr![i32; 2, 3, 4]); + /// ``` + fn pop_front(self) -> (T, Self::Shorter); +} + +unsafe impl> Lengthen for GenericArray +where + N: Add, + Add1: ArrayLength, + Add1: Sub, + Sub1>: ArrayLength, +{ + type Longer = GenericArray>; + + fn append(self, last: T) -> Self::Longer { + let mut longer: Self::Longer = unsafe { mem::uninitialized() }; + + unsafe { + ptr::write(longer.as_mut_ptr() as *mut _, self); + ptr::write(&mut longer[N::to_usize()], last); + } + + longer + } + + fn prepend(self, first: T) -> Self::Longer { + let mut longer: Self::Longer = unsafe { mem::uninitialized() }; + + let longer_ptr = longer.as_mut_ptr(); + + unsafe { + ptr::write(longer_ptr as *mut _, first); + ptr::write(longer_ptr.offset(1) as *mut _, self); + } + + longer + } +} + +unsafe impl> Shorten for GenericArray +where + N: Sub, + Sub1: ArrayLength, + Sub1: Add, + Add1>: ArrayLength, +{ + type Shorter = GenericArray>; + + fn pop_back(self) -> (Self::Shorter, T) { + let init_ptr = self.as_ptr(); + let last_ptr = unsafe { init_ptr.offset(Sub1::::to_usize() as isize) }; + + let init = unsafe { ptr::read(init_ptr as _) }; + let last = unsafe { ptr::read(last_ptr as _) }; + + mem::forget(self); + + (init, last) + } + + fn pop_front(self) -> (T, Self::Shorter) { + let head_ptr = self.as_ptr(); + let tail_ptr = unsafe { head_ptr.offset(1) }; + + let head = unsafe { ptr::read(head_ptr as _) }; + let tail = unsafe { ptr::read(tail_ptr as _) }; + + mem::forget(self); + + (head, tail) + } +} + +/// Defines a `GenericSequence` that can be split into two parts at a given pivot index. +pub unsafe trait Split: GenericSequence +where + K: ArrayLength, +{ + /// First part of the resulting split array + type First: GenericSequence; + /// Second part of the resulting split array + type Second: GenericSequence; + + /// Splits an array at the given index, returning the separate parts of the array. + fn split(self) -> (Self::First, Self::Second); +} + +unsafe impl Split for GenericArray +where + N: ArrayLength, + K: ArrayLength, + N: Sub, + Diff: ArrayLength, +{ + type First = GenericArray; + type Second = GenericArray>; + + fn split(self) -> (Self::First, Self::Second) { + let head_ptr = self.as_ptr(); + let tail_ptr = unsafe { head_ptr.offset(K::to_usize() as isize) }; + + let head = unsafe { ptr::read(head_ptr as _) }; + let tail = unsafe { ptr::read(tail_ptr as _) }; + + mem::forget(self); + + (head, tail) + } +} + +/// Defines `GenericSequence`s which can be joined together, forming a larger array. +pub unsafe trait Concat: GenericSequence +where + M: ArrayLength, +{ + /// Sequence to be concatenated with `self` + type Rest: GenericSequence; + + /// Resulting sequence formed by the concatenation. + type Output: GenericSequence; + + /// Concatenate, or join, two sequences. + fn concat(self, rest: Self::Rest) -> Self::Output; +} + +unsafe impl Concat for GenericArray +where + N: ArrayLength + Add, + M: ArrayLength, + Sum: ArrayLength, +{ + type Rest = GenericArray; + type Output = GenericArray>; + + fn concat(self, rest: Self::Rest) -> Self::Output { + let mut output: Self::Output = unsafe { mem::uninitialized() }; + + let output_ptr = output.as_mut_ptr(); + + unsafe { + ptr::write(output_ptr as *mut _, self); + ptr::write(output_ptr.offset(N::to_usize() as isize) as *mut _, rest); + } + + output + } +} diff --git a/third_party/rust/generic-array/tests/arr.rs b/third_party/rust/generic-array/tests/arr.rs new file mode 100644 index 000000000000..461805a501af --- /dev/null +++ b/third_party/rust/generic-array/tests/arr.rs @@ -0,0 +1,27 @@ +#[macro_use] +extern crate generic_array; +extern crate typenum; + +#[test] +fn empty_without_trailing_comma() { + let ar = arr![u8; ]; + assert_eq!(format!("{:x}", ar), ""); +} + +#[test] +fn empty_with_trailing_comma() { + let ar = arr![u8; , ]; + assert_eq!(format!("{:x}", ar), ""); +} + +#[test] +fn without_trailing_comma() { + let ar = arr![u8; 10, 20, 30]; + assert_eq!(format!("{:x}", ar), "0a141e"); +} + +#[test] +fn with_trailing_comma() { + let ar = arr![u8; 10, 20, 30, ]; + assert_eq!(format!("{:x}", ar), "0a141e"); +} diff --git a/third_party/rust/generic-array/tests/generics.rs b/third_party/rust/generic-array/tests/generics.rs new file mode 100644 index 000000000000..952867b386e5 --- /dev/null +++ b/third_party/rust/generic-array/tests/generics.rs @@ -0,0 +1,98 @@ +#![recursion_limit = "128"] + +#[macro_use] +extern crate generic_array; + +use generic_array::typenum::consts::U4; + +use std::fmt::Debug; +use std::ops::Add; + +use generic_array::{GenericArray, ArrayLength}; +use generic_array::sequence::*; +use generic_array::functional::*; + +/// Example function using generics to pass N-length sequences and map them +pub fn generic_map(s: S) +where + S: FunctionalSequence, // `.map` + S::Item: Add, // `x + 1` + S: MappedGenericSequence, // `i32` -> `i32` + MappedSequence: Debug, // println! +{ + let a = s.map(|x| x + 1); + + println!("{:?}", a); +} + +/// Complex example function using generics to pass N-length sequences, zip them, and then map that result. +/// +/// If used with `GenericArray` specifically this isn't necessary +pub fn generic_sequence_zip_sum(a: A, b: B) -> i32 +where + A: FunctionalSequence, // `.zip` + B: FunctionalSequence, // `.zip` + A: MappedGenericSequence, // `i32` -> `i32` + B: MappedGenericSequence>, // `i32` -> `i32`, prove A and B can map to the same output + A::Item: Add, // `l + r` + MappedSequence: MappedGenericSequence + FunctionalSequence, // `.map` + SequenceItem>: Add, // `x + 1` + MappedSequence, i32, i32>: Debug, // `println!` + MappedSequence, i32, i32>: FunctionalSequence, // `.fold` + SequenceItem, i32, i32>>: Add // `x + a`, note the order +{ + let c = a.zip(b, |l, r| l + r).map(|x| x + 1); + + println!("{:?}", c); + + c.fold(0, |a, x| x + a) +} + +/// Super-simple fixed-length i32 `GenericArray`s +pub fn generic_array_plain_zip_sum(a: GenericArray, b: GenericArray) -> i32 { + a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a) +} + +pub fn generic_array_variable_length_zip_sum(a: GenericArray, b: GenericArray) -> i32 +where + N: ArrayLength, +{ + a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a) +} + +pub fn generic_array_same_type_variable_length_zip_sum(a: GenericArray, b: GenericArray) -> i32 +where + N: ArrayLength + ArrayLength<>::Output>, + T: Add, +{ + a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a) +} + +/// Complex example using fully generic `GenericArray`s with the same length. +/// +/// It's mostly just the repeated `Add` traits, which would be present in other systems anyway. +pub fn generic_array_zip_sum + ArrayLength>(a: GenericArray, b: GenericArray) -> i32 +where + A: Add, + N: ArrayLength<>::Output> + + ArrayLength<<>::Output as Add>::Output>, + >::Output: Add, + <>::Output as Add>::Output: Add, +{ + a.zip(b, |l, r| l + r).map(|x| x + 1).fold(0, |a, x| x + a) +} + +#[test] +fn test_generics() { + generic_map(arr![i32; 1, 2, 3, 4]); + + assert_eq!(generic_sequence_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28); + + assert_eq!(generic_array_plain_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28); + + assert_eq!(generic_array_variable_length_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28); + + assert_eq!(generic_array_same_type_variable_length_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28); + + assert_eq!(generic_array_zip_sum(arr![i32; 1, 2, 3, 4], arr![i32; 2, 3, 4, 5]), 28); +} \ No newline at end of file diff --git a/third_party/rust/generic-array/tests/hex.rs b/third_party/rust/generic-array/tests/hex.rs index aed69e424979..0c63391a646b 100644 --- a/third_party/rust/generic-array/tests/hex.rs +++ b/third_party/rust/generic-array/tests/hex.rs @@ -1,44 +1,61 @@ -#[macro_use] -extern crate generic_array; -extern crate typenum; - -use generic_array::GenericArray; -use std::str::from_utf8; -use typenum::U2048; - - -#[test] -fn short_lower_hex() { - let ar = arr![u8; 10, 20, 30]; - assert_eq!(format!("{:x}", ar), "0a141e"); -} - -#[test] -fn short_upper_hex() { - let ar = arr![u8; 30, 20, 10]; - assert_eq!(format!("{:X}", ar), "1E140A"); -} - -#[test] -fn long_lower_hex() { - let ar = GenericArray::::default(); - assert_eq!(format!("{:x}", ar), from_utf8(&[b'0'; 4096]).unwrap()); -} - -#[test] -fn long_upper_hex() { - let ar = GenericArray::::default(); - assert_eq!(format!("{:X}", ar), from_utf8(&[b'0'; 4096]).unwrap()); -} - -#[test] -fn truncated_lower_hex() { - let ar = arr![u8; 10, 20, 30, 40, 50]; - assert_eq!(format!("{:.2x}", ar), "0a14"); -} - -#[test] -fn truncated_upper_hex() { - let ar = arr![u8; 30, 20, 10, 17, 0]; - assert_eq!(format!("{:.4X}", ar), "1E140A11"); -} +#[macro_use] +extern crate generic_array; +extern crate typenum; + +use generic_array::GenericArray; +use std::str::from_utf8; +use typenum::U2048; + +#[test] +fn short_lower_hex() { + let ar = arr![u8; 10, 20, 30]; + assert_eq!(format!("{:x}", ar), "0a141e"); +} + +#[test] +fn short_upper_hex() { + let ar = arr![u8; 30, 20, 10]; + assert_eq!(format!("{:X}", ar), "1E140A"); +} + +#[test] +fn long_lower_hex() { + let ar = GenericArray::::default(); + assert_eq!(format!("{:x}", ar), from_utf8(&[b'0'; 4096]).unwrap()); +} + +#[test] +fn long_lower_hex_truncated() { + let ar = GenericArray::::default(); + assert_eq!(format!("{:.3001x}", ar), from_utf8(&[b'0'; 3001]).unwrap()); +} + +#[test] +fn long_upper_hex() { + let ar = GenericArray::::default(); + assert_eq!(format!("{:X}", ar), from_utf8(&[b'0'; 4096]).unwrap()); +} + +#[test] +fn long_upper_hex_truncated() { + let ar = GenericArray::::default(); + assert_eq!(format!("{:.2777X}", ar), from_utf8(&[b'0'; 2777]).unwrap()); +} + +#[test] +fn truncated_lower_hex() { + let ar = arr![u8; 10, 20, 30, 40, 50]; + assert_eq!(format!("{:.2x}", ar), "0a"); + assert_eq!(format!("{:.3x}", ar), "0a1"); + assert_eq!(format!("{:.4x}", ar), "0a14"); +} + +#[test] +fn truncated_upper_hex() { + let ar = arr![u8; 30, 20, 10, 17, 0]; + assert_eq!(format!("{:.4X}", ar), "1E14"); + assert_eq!(format!("{:.5X}", ar), "1E140"); + assert_eq!(format!("{:.6X}", ar), "1E140A"); + assert_eq!(format!("{:.7X}", ar), "1E140A1"); + assert_eq!(format!("{:.8X}", ar), "1E140A11"); +} diff --git a/third_party/rust/generic-array/tests/import_name.rs b/third_party/rust/generic-array/tests/import_name.rs index 27653c9a85d7..f59f1b6c56f0 100644 --- a/third_party/rust/generic-array/tests/import_name.rs +++ b/third_party/rust/generic-array/tests/import_name.rs @@ -1,10 +1,10 @@ -#[macro_use] -extern crate generic_array as gen_arr; - -use gen_arr::typenum; - -#[test] -fn test_different_crate_name() { - let _: gen_arr::GenericArray = arr![u32; 0, 1, 2, 3]; - let _: gen_arr::GenericArray = arr![u32;]; -} +#[macro_use] +extern crate generic_array as gen_arr; + +use gen_arr::typenum; + +#[test] +fn test_different_crate_name() { + let _: gen_arr::GenericArray = arr![u32; 0, 1, 2, 3]; + let _: gen_arr::GenericArray = arr![u32;]; +} diff --git a/third_party/rust/generic-array/tests/iter.rs b/third_party/rust/generic-array/tests/iter.rs new file mode 100644 index 000000000000..19d198cb58dd --- /dev/null +++ b/third_party/rust/generic-array/tests/iter.rs @@ -0,0 +1,164 @@ +#[macro_use] +extern crate generic_array; + +use std::cell::Cell; +use std::ops::Drop; + +use generic_array::GenericArray; +use generic_array::typenum::consts::U5; + +#[test] +fn test_into_iter_as_slice() { + let array = arr![char; 'a', 'b', 'c']; + let mut into_iter = array.into_iter(); + assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); + let _ = into_iter.next().unwrap(); + assert_eq!(into_iter.as_slice(), &['b', 'c']); + let _ = into_iter.next().unwrap(); + let _ = into_iter.next().unwrap(); + assert_eq!(into_iter.as_slice(), &[]); +} + +#[test] +fn test_into_iter_as_mut_slice() { + let array = arr![char; 'a', 'b', 'c']; + let mut into_iter = array.into_iter(); + assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']); + into_iter.as_mut_slice()[0] = 'x'; + into_iter.as_mut_slice()[1] = 'y'; + assert_eq!(into_iter.next().unwrap(), 'x'); + assert_eq!(into_iter.as_slice(), &['y', 'c']); +} + +#[test] +fn test_into_iter_debug() { + let array = arr![char; 'a', 'b', 'c']; + let into_iter = array.into_iter(); + let debug = format!("{:?}", into_iter); + assert_eq!(debug, "GenericArrayIter(['a', 'b', 'c'])"); +} + +#[test] +fn test_into_iter_clone() { + fn iter_equal>(it: I, slice: &[i32]) { + let v: Vec = it.collect(); + assert_eq!(&v[..], slice); + } + let mut it = arr![i32; 1, 2, 3].into_iter(); + iter_equal(it.clone(), &[1, 2, 3]); + assert_eq!(it.next(), Some(1)); + let mut it = it.rev(); + iter_equal(it.clone(), &[3, 2]); + assert_eq!(it.next(), Some(3)); + iter_equal(it.clone(), &[2]); + assert_eq!(it.next(), Some(2)); + iter_equal(it.clone(), &[]); + assert_eq!(it.next(), None); +} + +#[test] +fn test_into_iter_nth() { + let v = arr![i32; 0, 1, 2, 3, 4]; + for i in 0..v.len() { + assert_eq!(v.clone().into_iter().nth(i).unwrap(), v[i]); + } + assert_eq!(v.clone().into_iter().nth(v.len()), None); + + let mut iter = v.into_iter(); + assert_eq!(iter.nth(2).unwrap(), v[2]); + assert_eq!(iter.nth(1).unwrap(), v[4]); +} + +#[test] +fn test_into_iter_last() { + let v = arr![i32; 0, 1, 2, 3, 4]; + assert_eq!(v.into_iter().last().unwrap(), 4); + assert_eq!(arr![i32; 0].into_iter().last().unwrap(), 0); +} + +#[test] +fn test_into_iter_count() { + let v = arr![i32; 0, 1, 2, 3, 4]; + assert_eq!(v.clone().into_iter().count(), 5); + + let mut iter2 = v.into_iter(); + iter2.next(); + iter2.next(); + assert_eq!(iter2.count(), 3); +} + +#[test] +fn test_into_iter_flat_map() { + assert!((0..5).flat_map(|i| arr![i32; 2 * i, 2 * i + 1]).eq(0..10)); +} + +#[test] +fn test_into_iter_drops() { + struct R<'a> { + i: &'a Cell, + } + + impl<'a> Drop for R<'a> { + fn drop(&mut self) { + self.i.set(self.i.get() + 1); + } + } + + fn r(i: &Cell) -> R { + R { + i: i + } + } + + fn v(i: &Cell) -> GenericArray { + arr![R; r(i), r(i), r(i), r(i), r(i)] + } + + let i = Cell::new(0); + { + v(&i).into_iter(); + } + assert_eq!(i.get(), 5); + + let i = Cell::new(0); + { + let mut iter = v(&i).into_iter(); + let _x = iter.next(); + assert_eq!(i.get(), 0); + assert_eq!(iter.count(), 4); + assert_eq!(i.get(), 4); + } + assert_eq!(i.get(), 5); + + let i = Cell::new(0); + { + let mut iter = v(&i).into_iter(); + let _x = iter.nth(2); + assert_eq!(i.get(), 2); + let _y = iter.last(); + assert_eq!(i.get(), 3); + } + assert_eq!(i.get(), 5); + + let i = Cell::new(0); + for (index, _x) in v(&i).into_iter().enumerate() { + assert_eq!(i.get(), index); + } + assert_eq!(i.get(), 5); + + let i = Cell::new(0); + for (index, _x) in v(&i).into_iter().rev().enumerate() { + assert_eq!(i.get(), index); + } + assert_eq!(i.get(), 5); +} + +/* +//TODO: Cover this +#[allow(dead_code)] +fn assert_covariance() { + fn into_iter<'new>(i: GenericArrayIter<&'static str, U10>) -> GenericArrayIter<&'new str, U10> { + i + } +} +*/ \ No newline at end of file diff --git a/third_party/rust/generic-array/tests/mod.rs b/third_party/rust/generic-array/tests/mod.rs index 2a2f2e15f7c5..c103f417ab9f 100644 --- a/third_party/rust/generic-array/tests/mod.rs +++ b/third_party/rust/generic-array/tests/mod.rs @@ -1,169 +1,287 @@ -#![recursion_limit="128"] -#![no_std] -#[macro_use] -extern crate generic_array; -use core::cell::Cell; -use core::ops::Drop; -use generic_array::GenericArray; -use generic_array::typenum::{U1, U3, U4, U97}; - -#[test] -fn test() { - let mut list97 = [0; 97]; - for i in 0..97 { - list97[i] = i as i32; - } - let l: GenericArray = GenericArray::clone_from_slice(&list97); - assert_eq!(l[0], 0); - assert_eq!(l[1], 1); - assert_eq!(l[32], 32); - assert_eq!(l[56], 56); -} - -#[test] -fn test_drop() { - #[derive(Clone)] - struct TestDrop<'a>(&'a Cell); - - impl<'a> Drop for TestDrop<'a> { - fn drop(&mut self) { - self.0.set(self.0.get() + 1); - } - } - - let drop_counter = Cell::new(0); - { - let _: GenericArray = - arr![TestDrop; TestDrop(&drop_counter), - TestDrop(&drop_counter), - TestDrop(&drop_counter)]; - } - assert_eq!(drop_counter.get(), 3); -} - -#[test] -fn test_arr() { - let test: GenericArray = arr![u32; 1, 2, 3]; - assert_eq!(test[1], 2); -} - -#[test] -fn test_copy() { - let test = arr![u32; 1, 2, 3]; - let test2 = test; - // if GenericArray is not copy, this should fail as a use of a moved value - assert_eq!(test[1], 2); - assert_eq!(test2[0], 1); -} - -#[test] -fn test_iter_flat_map() { - assert!((0..5).flat_map(|i| arr![i32; 2 * i, 2 * i + 1]).eq(0..10)); -} - -#[derive(Debug, PartialEq, Eq)] -struct NoClone(T); - -#[test] -fn test_from_slice() { - let arr = [1, 2, 3, 4]; - let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]); - assert_eq!(&arr[..3], gen_arr.as_slice()); - let arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)]; - let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]); - assert_eq!(&arr[..3], gen_arr.as_slice()); -} - -#[test] -fn test_from_mut_slice() { - let mut arr = [1, 2, 3, 4]; - { - let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]); - gen_arr[2] = 10; - } - assert_eq!(arr, [1, 2, 10, 4]); - let mut arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)]; - { - let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]); - gen_arr[2] = NoClone(10); - } - assert_eq!(arr, [NoClone(1), NoClone(2), NoClone(10), NoClone(4)]); -} - -#[test] -fn test_default() { - let arr = GenericArray::::default(); - assert_eq!(arr[0], 0); -} - -#[test] -fn test_from() { - let data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]; - let garray: GenericArray<(usize, usize, usize), U3> = data.into(); - assert_eq!(&data, garray.as_slice()); -} - -#[test] -fn test_unit_macro() { - let arr = arr![f32; 3.14]; - assert_eq!(arr[0], 3.14); -} - -#[test] -fn test_empty_macro() { - let _arr = arr![f32;]; -} - -#[test] -fn test_cmp() { - arr![u8; 0x00].cmp(&arr![u8; 0x00]); -} - -/// This test should cause a helpful compile error if uncommented. -// #[test] -// fn test_empty_macro2(){ -// let arr = arr![]; -// } -#[cfg(feature = "serde")] -mod impl_serde { - extern crate serde_json; - - use generic_array::GenericArray; - use generic_array::typenum::U6; - - #[test] - fn test_serde_implementation() { - let array: GenericArray = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0]; - let string = serde_json::to_string(&array).unwrap(); - assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]"); - - let test_array: GenericArray = serde_json::from_str(&string).unwrap(); - assert_eq!(test_array, array); - } -} - -#[test] -fn test_map() { - let b: GenericArray = GenericArray::generate(|i| i as i32 * 4).map(|x| x - 3); - - assert_eq!(b, arr![i32; -3, 1, 5, 9]); -} - -#[test] -fn test_zip() { - let a: GenericArray<_, U4> = GenericArray::generate(|i| i + 1); - let b: GenericArray<_, U4> = GenericArray::generate(|i| i as i32 * 4); - - let c = a.zip(b, |r, l| r as i32 + l); - - assert_eq!(c, arr![i32; 1, 6, 11, 16]); -} - -#[test] -fn test_from_iter() { - use core::iter::repeat; - - let a: GenericArray<_, U4> = repeat(11).take(3).collect(); - - assert_eq!(a, arr![i32; 11, 11, 11, 0]); -} +#![recursion_limit = "128"] +#![no_std] +#[macro_use] +extern crate generic_array; +use core::cell::Cell; +use core::ops::{Add, Drop}; +use generic_array::GenericArray; +use generic_array::functional::*; +use generic_array::sequence::*; +use generic_array::typenum::{U1, U3, U4, U97}; + +#[test] +fn test() { + let mut list97 = [0; 97]; + for i in 0..97 { + list97[i] = i as i32; + } + let l: GenericArray = GenericArray::clone_from_slice(&list97); + assert_eq!(l[0], 0); + assert_eq!(l[1], 1); + assert_eq!(l[32], 32); + assert_eq!(l[56], 56); +} + +#[test] +fn test_drop() { + #[derive(Clone)] + struct TestDrop<'a>(&'a Cell); + + impl<'a> Drop for TestDrop<'a> { + fn drop(&mut self) { + self.0.set(self.0.get() + 1); + } + } + + let drop_counter = Cell::new(0); + { + let _: GenericArray = arr![TestDrop; TestDrop(&drop_counter), + TestDrop(&drop_counter), + TestDrop(&drop_counter)]; + } + assert_eq!(drop_counter.get(), 3); +} + +#[test] +fn test_arr() { + let test: GenericArray = arr![u32; 1, 2, 3]; + assert_eq!(test[1], 2); +} + +#[test] +fn test_copy() { + let test = arr![u32; 1, 2, 3]; + let test2 = test; + // if GenericArray is not copy, this should fail as a use of a moved value + assert_eq!(test[1], 2); + assert_eq!(test2[0], 1); +} + +#[derive(Debug, PartialEq, Eq)] +struct NoClone(T); + +#[test] +fn test_from_slice() { + let arr = [1, 2, 3, 4]; + let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]); + assert_eq!(&arr[..3], gen_arr.as_slice()); + let arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)]; + let gen_arr = GenericArray::<_, U3>::from_slice(&arr[..3]); + assert_eq!(&arr[..3], gen_arr.as_slice()); +} + +#[test] +fn test_from_mut_slice() { + let mut arr = [1, 2, 3, 4]; + { + let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]); + gen_arr[2] = 10; + } + assert_eq!(arr, [1, 2, 10, 4]); + let mut arr = [NoClone(1u32), NoClone(2), NoClone(3), NoClone(4)]; + { + let gen_arr = GenericArray::<_, U3>::from_mut_slice(&mut arr[..3]); + gen_arr[2] = NoClone(10); + } + assert_eq!(arr, [NoClone(1), NoClone(2), NoClone(10), NoClone(4)]); +} + +#[test] +fn test_default() { + let arr = GenericArray::::default(); + assert_eq!(arr[0], 0); +} + +#[test] +fn test_from() { + let data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]; + let garray: GenericArray<(usize, usize, usize), U3> = data.into(); + assert_eq!(&data, garray.as_slice()); +} + +#[test] +fn test_unit_macro() { + let arr = arr![f32; 3.14]; + assert_eq!(arr[0], 3.14); +} + +#[test] +fn test_empty_macro() { + let _arr = arr![f32;]; +} + +#[test] +fn test_cmp() { + arr![u8; 0x00].cmp(&arr![u8; 0x00]); +} + +/// This test should cause a helpful compile error if uncommented. +// #[test] +// fn test_empty_macro2(){ +// let arr = arr![]; +// } +#[cfg(feature = "serde")] +mod impl_serde { + extern crate serde_json; + + use generic_array::GenericArray; + use generic_array::typenum::U6; + + #[test] + fn test_serde_implementation() { + let array: GenericArray = arr![f64; 0.0, 5.0, 3.0, 7.07192, 76.0, -9.0]; + let string = serde_json::to_string(&array).unwrap(); + assert_eq!(string, "[0.0,5.0,3.0,7.07192,76.0,-9.0]"); + + let test_array: GenericArray = serde_json::from_str(&string).unwrap(); + assert_eq!(test_array, array); + } +} + +#[test] +fn test_map() { + let b: GenericArray = GenericArray::generate(|i| i as i32 * 4).map(|x| x - 3); + + assert_eq!(b, arr![i32; -3, 1, 5, 9]); +} + +#[test] +fn test_zip() { + let a: GenericArray<_, U4> = GenericArray::generate(|i| i + 1); + let b: GenericArray<_, U4> = GenericArray::generate(|i| i as i32 * 4); + + // Uses reference and non-reference arguments + let c = (&a).zip(b, |r, l| *r as i32 + l); + + assert_eq!(c, arr![i32; 1, 6, 11, 16]); +} + +#[test] +#[should_panic] +fn test_from_iter_short() { + use core::iter::repeat; + + let a: GenericArray<_, U4> = repeat(11).take(3).collect(); + + assert_eq!(a, arr![i32; 11, 11, 11, 0]); +} + +#[test] +fn test_from_iter() { + use core::iter::{once, repeat}; + + let a: GenericArray<_, U4> = repeat(11).take(3).chain(once(0)).collect(); + + assert_eq!(a, arr![i32; 11, 11, 11, 0]); +} + +#[test] +fn test_sizes() { + #![allow(dead_code)] + use core::mem::{size_of, size_of_val}; + + #[derive(Debug, Copy, Clone)] + #[repr(C)] + #[repr(packed)] + struct Test { + t: u16, + s: u32, + r: u16, + f: u16, + o: u32, + } + + assert_eq!(size_of::(), 14); + + assert_eq!(size_of_val(&arr![u8; 1, 2, 3]), size_of::() * 3); + assert_eq!(size_of_val(&arr![u32; 1]), size_of::() * 1); + assert_eq!(size_of_val(&arr![u64; 1, 2, 3, 4]), size_of::() * 4); + + assert_eq!(size_of::>(), size_of::() * 97); +} + +#[test] +fn test_append() { + let a = arr![i32; 1, 2, 3]; + + let b = a.append(4); + + assert_eq!(b, arr![i32; 1, 2, 3, 4]); +} + +#[test] +fn test_prepend() { + let a = arr![i32; 1, 2, 3]; + + let b = a.prepend(4); + + assert_eq!(b, arr![i32; 4, 1, 2, 3]); +} + +#[test] +fn test_pop() { + let a = arr![i32; 1, 2, 3, 4]; + + let (init, last) = a.pop_back(); + + assert_eq!(init, arr![i32; 1, 2, 3]); + assert_eq!(last, 4); + + let (head, tail) = a.pop_front(); + + assert_eq!(head, 1); + assert_eq!(tail, arr![i32; 2, 3, 4]); +} + +#[test] +fn test_split() { + let a = arr![i32; 1, 2, 3, 4]; + + let (b, c) = a.split(); + + assert_eq!(b, arr![i32; 1]); + assert_eq!(c, arr![i32; 2, 3, 4]); + + let (e, f) = a.split(); + + assert_eq!(e, arr![i32; 1, 2]); + assert_eq!(f, arr![i32; 3, 4]); +} + +#[test] +fn test_concat() { + let a = arr![i32; 1, 2]; + let b = arr![i32; 3, 4]; + + let c = a.concat(b); + + assert_eq!(c, arr![i32; 1, 2, 3, 4]); + + let (d, e) = c.split(); + + assert_eq!(d, arr![i32; 1]); + assert_eq!(e, arr![i32; 2, 3, 4]); +} + +#[test] +fn test_fold() { + let a = arr![i32; 1, 2, 3, 4]; + + assert_eq!(10, a.fold(0, |a, x| a + x)); +} + +fn sum_generic(s: S) -> i32 +where + S: FunctionalSequence, + S::Item: Add, // `+` + i32: Add, // reflexive +{ + s.fold(0, |a, x| a + x) +} + +#[test] +fn test_sum() { + let a = sum_generic(arr![i32; 1, 2, 3, 4]); + + assert_eq!(a, 10); +} diff --git a/third_party/rust/opaque-debug/.cargo-checksum.json b/third_party/rust/opaque-debug/.cargo-checksum.json new file mode 100644 index 000000000000..3f1711dc2d02 --- /dev/null +++ b/third_party/rust/opaque-debug/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"14c835bd1efdb7293220cb4d4ed2d332f2e7512a46e9a185bdb68d66f390fbc2","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/lib.rs":"e4730f0693ba6e8a4e481bea655ede96775f8eb4c0f94f1af740acb2a11240be"},"package":"51ecbcb821e1bd256d456fe858aaa7f380b63863eab2eb86eee1bd9f33dd6682"} \ No newline at end of file diff --git a/third_party/rust/opaque-debug/Cargo.toml b/third_party/rust/opaque-debug/Cargo.toml new file mode 100644 index 000000000000..987493bb57b7 --- /dev/null +++ b/third_party/rust/opaque-debug/Cargo.toml @@ -0,0 +1,22 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "opaque-debug" +version = "0.2.1" +authors = ["RustCrypto Developers"] +description = "Macro for opaque Debug trait implementation" +documentation = "https://docs.rs/opaque-debug" +license = "MIT/Apache-2.0" +repository = "https://github.com/RustCrypto/utils" + +[dependencies] diff --git a/third_party/rust/opaque-debug/LICENSE-APACHE b/third_party/rust/opaque-debug/LICENSE-APACHE new file mode 100644 index 000000000000..78173fa2e753 --- /dev/null +++ b/third_party/rust/opaque-debug/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/opaque-debug/LICENSE-MIT b/third_party/rust/opaque-debug/LICENSE-MIT new file mode 100644 index 000000000000..8dcb85b30273 --- /dev/null +++ b/third_party/rust/opaque-debug/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2017 Artyom Pavlov + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/opaque-debug/src/lib.rs b/third_party/rust/opaque-debug/src/lib.rs new file mode 100644 index 000000000000..c3648c35f445 --- /dev/null +++ b/third_party/rust/opaque-debug/src/lib.rs @@ -0,0 +1,31 @@ +//! Macro for opaque `Debug` trait implementation. +#![no_std] + +/// Macro for defining opaque `Debug` implementation. +/// +/// It will use the following format: "StructName { ... }". While it's +/// convinient to have it (e.g. for including into other structs), it could be +/// undesirable to leak internall state, which can happen for example through +/// uncareful logging. +#[macro_export] +macro_rules! impl_opaque_debug { + ($struct:ty) => { + #[cfg(feature = "std")] + impl ::std::fmt::Debug for $struct { + fn fmt(&self, f: &mut ::std::fmt::Formatter) + -> Result<(), ::std::fmt::Error> + { + write!(f, concat!(stringify!($struct), " {{ ... }}")) + } + } + + #[cfg(not(feature = "std"))] + impl ::core::fmt::Debug for $struct { + fn fmt(&self, f: &mut ::core::fmt::Formatter) + -> Result<(), ::core::fmt::Error> + { + write!(f, concat!(stringify!($struct), " {{ ... }}")) + } + } + } +} diff --git a/third_party/rust/sha2-0.7.1/.cargo-checksum.json b/third_party/rust/sha2-0.7.1/.cargo-checksum.json new file mode 100644 index 000000000000..6144e702f3d3 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"1edde1679db6070037fff3fe48cfacc14ac1ce9fd59142a629ec948ba272158b","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"b4eb00df6e2a4d22518fcaa6a2b4646f249b3a3c9814509b22bd2091f1392ff1","benches/sha256.rs":"221b7fc2f43cb57094adfdf3f422d24fead8c87653d3fb36b764f103542d7cef","benches/sha512.rs":"0455cf7e63c3145eb109f860e81a0c1af504b61456e8d2372ac5e158e95c1b30","examples/sha256sum.rs":"82f5c111cfc3c6db386b2e1ed300e0f45cd781d6b0f291537e3db9f390dfb79b","examples/sha512sum.rs":"ba7690db22ff7ac7f5884bde6896a54ac6a82f05802e118d2f8c5458198687a6","src/consts.rs":"06e7bae76155291d1f896b72b625500859fbcfb80ee948ab3919620c96320610","src/lib.rs":"05c31c49cd10f421028acb37c52fcffec6b6006e47274a212e906c9fd7c62199","src/sha256.rs":"17e6efc69c3910b05116e44aabef22b2b770b4d42fba53465ba07dee5f211eab","src/sha256_utils.rs":"4d764643ee34a5387d4deea26e12ad6d8d51480fe3e3c502dcbe97bb8b3148a0","src/sha512.rs":"ccc6679ddb21d11abefd940e119ae78eee8214d44446ff7186797feed70d2e45","src/sha512_utils.rs":"0b67350b0f796981290e152a1020275527d6e0ed902328097b1ee1c7dfaedf5c","tests/data/sha224/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha224/test1.output.bin":"70e01c74bb4c4b3e5b2dc7cba0694f9bc78e220e89e1f133f62c38781ebd1378","tests/data/sha224/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha224/test2.output.bin":"7cfed1501838fd337c201c54ab622bf2337edded6aac84a978cff9f1db267c08","tests/data/sha224/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha224/test3.output.bin":"3fea089ea073f5b90609aa1bcef080c3af270e3c57fc142f6aaec9a6e041f347","tests/data/sha256/one_million_a.output.bin":"80d1189477563e1b5206b2749f1afe4807e5705e8bd77887a60187a712156688","tests/data/sha256/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha256/test1.output.bin":"5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456","tests/data/sha256/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha256/test2.output.bin":"6d37795021e544d82b41850edf7aabab9a0ebe274e54a519840c4666f35b3937","tests/data/sha256/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha256/test3.output.bin":"a51a910ecba8a599555b32133bf1829455d55fe576677b49cb561d874077385c","tests/data/sha384/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha384/test1.output.bin":"4800fbfc4566eb02d1727a4b1c949ccbc7535c216a0766564c199308631b5dd6","tests/data/sha384/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha384/test2.output.bin":"0743eb48e2913c5d5d963ec13a4515ec2f9ca6ffe72e91a935871b2bff2103a0","tests/data/sha384/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha384/test3.output.bin":"b3917c6fb1f65c2b91fdbfe3a484f171949f27f3980796f4ae1b31ec9841d0f6","tests/data/sha512/one_million_a.output.bin":"a872d736156b28b7784fcc124cfb9993ed31707f1754a0a448d26bf84f5cc7f5","tests/data/sha512/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha512/test1.output.bin":"001d686db504e20c792eaa07fe09224a45ff328e24a80072d04d16abc5c2b5d2","tests/data/sha512/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha512/test2.output.bin":"372efde43fa80632b3a582d8908909f25d628928242d44531e7bef0012f6c811","tests/data/sha512/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha512/test3.output.bin":"53e379e5e4d9afd6229cb1bbb8698a59e311ed6c7111c2f8239be08f081b88d0","tests/data/sha512_224/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha512_224/test1.output.bin":"480be8cbde48b8416d5576ed5909ae9adbc4054b8e2b3ebdd5c63326f52ec4fc","tests/data/sha512_224/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha512_224/test2.output.bin":"cb5de67a5f215eb179fa45a2bb3f1b4583bbd2f510c90c21486aa47054f9745a","tests/data/sha512_224/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha512_224/test3.output.bin":"2a664dfa12b7b792709bea1a44b64eba03862a0ca60e251e99c6e05f94467c79","tests/data/sha512_256/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha512_256/test1.output.bin":"5a480c713c47fb00a9b4943583ca0401fc147cce25efdc2594f958a4aeeafe48","tests/data/sha512_256/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha512_256/test2.output.bin":"906e1d233a2d982ffe13f14b9bdc9c4229857dfdd5ec17be732d8fa4b7cc00cc","tests/data/sha512_256/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha512_256/test3.output.bin":"5ecc2545c93c4465c022b07ee5ff58d9b42fd91e1577bff7284e63f4c7c08d2e","tests/lib.rs":"52b23f0c2f72b88bfadca0dfdb0a0709e1157c53a9221d54484d75db4b747385"},"package":"9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"} \ No newline at end of file diff --git a/third_party/rust/sha2-0.7.1/Cargo.toml b/third_party/rust/sha2-0.7.1/Cargo.toml new file mode 100644 index 000000000000..8a062c76c088 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/Cargo.toml @@ -0,0 +1,45 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "sha2" +version = "0.7.1" +authors = ["RustCrypto Developers"] +description = "SHA-2 hash functions" +documentation = "https://docs.rs/sha2" +keywords = ["crypto", "sha2", "hash", "digest"] +categories = ["cryptography", "no-std"] +license = "MIT/Apache-2.0" +repository = "https://github.com/RustCrypto/hashes" +[dependencies.block-buffer] +version = "0.3" + +[dependencies.byte-tools] +version = "0.2" + +[dependencies.digest] +version = "0.7" + +[dependencies.fake-simd] +version = "0.1" + +[dependencies.sha2-asm] +version = "0.5" +optional = true +[dev-dependencies.digest] +version = "^0.7.1" +features = ["dev"] + +[features] +asm = ["sha2-asm"] +[badges.travis-ci] +repository = "RustCrypto/hashes" diff --git a/third_party/rust/sha2-0.7.1/LICENSE-APACHE b/third_party/rust/sha2-0.7.1/LICENSE-APACHE new file mode 100644 index 000000000000..78173fa2e753 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/sha2-0.7.1/LICENSE-MIT b/third_party/rust/sha2-0.7.1/LICENSE-MIT new file mode 100644 index 000000000000..66cf75563b39 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/LICENSE-MIT @@ -0,0 +1,27 @@ +Copyright (c) 2006-2009 Graydon Hoare +Copyright (c) 2009-2013 Mozilla Foundation +Copyright (c) 2016 Artyom Pavlov + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/sha2-0.7.1/benches/sha256.rs b/third_party/rust/sha2-0.7.1/benches/sha256.rs new file mode 100644 index 000000000000..fdb80f664ec7 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/benches/sha256.rs @@ -0,0 +1,7 @@ +#![no_std] +#![feature(test)] +#[macro_use] +extern crate digest; +extern crate sha2; + +bench_digest!(sha2::Sha256); diff --git a/third_party/rust/sha2-0.7.1/benches/sha512.rs b/third_party/rust/sha2-0.7.1/benches/sha512.rs new file mode 100644 index 000000000000..69dd87b44274 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/benches/sha512.rs @@ -0,0 +1,7 @@ +#![no_std] +#![feature(test)] +#[macro_use] +extern crate digest; +extern crate sha2; + +bench_digest!(sha2::Sha512); diff --git a/third_party/rust/sha2-0.7.1/examples/sha256sum.rs b/third_party/rust/sha2-0.7.1/examples/sha256sum.rs new file mode 100644 index 000000000000..96bf2abc22ff --- /dev/null +++ b/third_party/rust/sha2-0.7.1/examples/sha256sum.rs @@ -0,0 +1,49 @@ +extern crate sha2; + +use sha2::{Sha256, Digest}; +use std::env; +use std::fs; +use std::io::{self, Read}; + +const BUFFER_SIZE: usize = 1024; + +/// Print digest result as hex string and name pair +fn print_result(sum: &[u8], name: &str) { + for byte in sum { + print!("{:02x}", byte); + } + println!("\t{}", name); +} + +/// Compute digest value for given `Reader` and print it +/// On any error simply return without doing anything +fn process(reader: &mut R, name: &str) { + let mut sh = D::default(); + let mut buffer = [0u8; BUFFER_SIZE]; + loop { + let n = match reader.read(&mut buffer) { + Ok(n) => n, + Err(_) => return, + }; + sh.input(&buffer[..n]); + if n == 0 || n < BUFFER_SIZE { + break; + } + } + print_result(&sh.result(), name); +} + +fn main() { + let args = env::args(); + // Process files listed in command line arguments one by one + // If no files provided process input from stdin + if args.len() > 1 { + for path in args.skip(1) { + if let Ok(mut file) = fs::File::open(&path) { + process::(&mut file, &path); + } + } + } else { + process::(&mut io::stdin(), "-"); + } +} diff --git a/third_party/rust/sha2-0.7.1/examples/sha512sum.rs b/third_party/rust/sha2-0.7.1/examples/sha512sum.rs new file mode 100644 index 000000000000..5b59d8aa768c --- /dev/null +++ b/third_party/rust/sha2-0.7.1/examples/sha512sum.rs @@ -0,0 +1,49 @@ +extern crate sha2; + +use sha2::{Sha512, Digest}; +use std::env; +use std::fs; +use std::io::{self, Read}; + +const BUFFER_SIZE: usize = 1024; + +/// Print digest result as hex string and name pair +fn print_result(sum: &[u8], name: &str) { + for byte in sum { + print!("{:02x}", byte); + } + println!("\t{}", name); +} + +/// Compute digest value for given `Reader` and print it +/// On any error simply return without doing anything +fn process(reader: &mut R, name: &str) { + let mut sh = D::default(); + let mut buffer = [0u8; BUFFER_SIZE]; + loop { + let n = match reader.read(&mut buffer) { + Ok(n) => n, + Err(_) => return, + }; + sh.input(&buffer[..n]); + if n == 0 || n < BUFFER_SIZE { + break; + } + } + print_result(&sh.result(), name); +} + +fn main() { + let args = env::args(); + // Process files listed in command line arguments one by one + // If no files provided process input from stdin + if args.len() > 1 { + for path in args.skip(1) { + if let Ok(mut file) = fs::File::open(&path) { + process::(&mut file, &path); + } + } + } else { + process::(&mut io::stdin(), "-"); + } +} diff --git a/third_party/rust/sha2-0.7.1/src/consts.rs b/third_party/rust/sha2-0.7.1/src/consts.rs new file mode 100644 index 000000000000..fc96b401a50c --- /dev/null +++ b/third_party/rust/sha2-0.7.1/src/consts.rs @@ -0,0 +1,200 @@ +#![allow(dead_code)] +#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))] + +use simd::u64x2; +use simd::u32x4; + +pub const STATE_LEN: usize = 8; +pub const BLOCK_LEN: usize = 16; + +/// Constants necessary for SHA-256 family of digests. +pub const K32: [u32; 64] = + [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]; + +/// Constants necessary for SHA-256 family of digests. +pub const K32X4: [u32x4; 16] = [u32x4(K32[3], K32[2], K32[1], K32[0]), + u32x4(K32[7], K32[6], K32[5], K32[4]), + u32x4(K32[11], K32[10], K32[9], K32[8]), + u32x4(K32[15], K32[14], K32[13], K32[12]), + u32x4(K32[19], K32[18], K32[17], K32[16]), + u32x4(K32[23], K32[22], K32[21], K32[20]), + u32x4(K32[27], K32[26], K32[25], K32[24]), + u32x4(K32[31], K32[30], K32[29], K32[28]), + u32x4(K32[35], K32[34], K32[33], K32[32]), + u32x4(K32[39], K32[38], K32[37], K32[36]), + u32x4(K32[43], K32[42], K32[41], K32[40]), + u32x4(K32[47], K32[46], K32[45], K32[44]), + u32x4(K32[51], K32[50], K32[49], K32[48]), + u32x4(K32[55], K32[54], K32[53], K32[52]), + u32x4(K32[59], K32[58], K32[57], K32[56]), + u32x4(K32[63], K32[62], K32[61], K32[60])]; + +/// Constants necessary for SHA-512 family of digests. +pub const K64: [u64; 80] = [0x428a2f98d728ae22, + 0x7137449123ef65cd, + 0xb5c0fbcfec4d3b2f, + 0xe9b5dba58189dbbc, + 0x3956c25bf348b538, + 0x59f111f1b605d019, + 0x923f82a4af194f9b, + 0xab1c5ed5da6d8118, + 0xd807aa98a3030242, + 0x12835b0145706fbe, + 0x243185be4ee4b28c, + 0x550c7dc3d5ffb4e2, + 0x72be5d74f27b896f, + 0x80deb1fe3b1696b1, + 0x9bdc06a725c71235, + 0xc19bf174cf692694, + 0xe49b69c19ef14ad2, + 0xefbe4786384f25e3, + 0x0fc19dc68b8cd5b5, + 0x240ca1cc77ac9c65, + 0x2de92c6f592b0275, + 0x4a7484aa6ea6e483, + 0x5cb0a9dcbd41fbd4, + 0x76f988da831153b5, + 0x983e5152ee66dfab, + 0xa831c66d2db43210, + 0xb00327c898fb213f, + 0xbf597fc7beef0ee4, + 0xc6e00bf33da88fc2, + 0xd5a79147930aa725, + 0x06ca6351e003826f, + 0x142929670a0e6e70, + 0x27b70a8546d22ffc, + 0x2e1b21385c26c926, + 0x4d2c6dfc5ac42aed, + 0x53380d139d95b3df, + 0x650a73548baf63de, + 0x766a0abb3c77b2a8, + 0x81c2c92e47edaee6, + 0x92722c851482353b, + 0xa2bfe8a14cf10364, + 0xa81a664bbc423001, + 0xc24b8b70d0f89791, + 0xc76c51a30654be30, + 0xd192e819d6ef5218, + 0xd69906245565a910, + 0xf40e35855771202a, + 0x106aa07032bbd1b8, + 0x19a4c116b8d2d0c8, + 0x1e376c085141ab53, + 0x2748774cdf8eeb99, + 0x34b0bcb5e19b48a8, + 0x391c0cb3c5c95a63, + 0x4ed8aa4ae3418acb, + 0x5b9cca4f7763e373, + 0x682e6ff3d6b2b8a3, + 0x748f82ee5defb2fc, + 0x78a5636f43172f60, + 0x84c87814a1f0ab72, + 0x8cc702081a6439ec, + 0x90befffa23631e28, + 0xa4506cebde82bde9, + 0xbef9a3f7b2c67915, + 0xc67178f2e372532b, + 0xca273eceea26619c, + 0xd186b8c721c0c207, + 0xeada7dd6cde0eb1e, + 0xf57d4f7fee6ed178, + 0x06f067aa72176fba, + 0x0a637dc5a2c898a6, + 0x113f9804bef90dae, + 0x1b710b35131c471b, + 0x28db77f523047d84, + 0x32caab7b40c72493, + 0x3c9ebe0a15c9bebc, + 0x431d67c49c100d4c, + 0x4cc5d4becb3e42b6, + 0x597f299cfc657e2a, + 0x5fcb6fab3ad6faec, + 0x6c44198c4a475817]; + +/// Constants necessary for SHA-512 family of digests. +pub const K64X2: [u64x2; 40] = [u64x2(K64[1], K64[0]), + u64x2(K64[3], K64[2]), + u64x2(K64[5], K64[4]), + u64x2(K64[7], K64[6]), + u64x2(K64[9], K64[8]), + u64x2(K64[11], K64[10]), + u64x2(K64[13], K64[12]), + u64x2(K64[15], K64[14]), + u64x2(K64[17], K64[16]), + u64x2(K64[19], K64[18]), + u64x2(K64[21], K64[20]), + u64x2(K64[23], K64[22]), + u64x2(K64[25], K64[24]), + u64x2(K64[27], K64[26]), + u64x2(K64[29], K64[28]), + u64x2(K64[31], K64[30]), + u64x2(K64[33], K64[32]), + u64x2(K64[35], K64[34]), + u64x2(K64[37], K64[36]), + u64x2(K64[39], K64[38]), + u64x2(K64[41], K64[40]), + u64x2(K64[43], K64[42]), + u64x2(K64[45], K64[44]), + u64x2(K64[47], K64[46]), + u64x2(K64[49], K64[48]), + u64x2(K64[51], K64[50]), + u64x2(K64[53], K64[52]), + u64x2(K64[55], K64[54]), + u64x2(K64[57], K64[56]), + u64x2(K64[59], K64[58]), + u64x2(K64[61], K64[60]), + u64x2(K64[63], K64[62]), + u64x2(K64[65], K64[64]), + u64x2(K64[67], K64[66]), + u64x2(K64[69], K64[68]), + u64x2(K64[71], K64[70]), + u64x2(K64[73], K64[72]), + u64x2(K64[75], K64[74]), + u64x2(K64[77], K64[76]), + u64x2(K64[79], K64[78])]; + +pub static H224: [u32; STATE_LEN] = [0xc1059ed8, 0x367cd507, 0x3070dd17, + 0xf70e5939, 0xffc00b31, 0x68581511, + 0x64f98fa7, 0xbefa4fa4]; + +pub static H256: [u32; STATE_LEN] = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, + 0xa54ff53a, 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19]; + +pub static H384: [u64; STATE_LEN] = [0xcbbb9d5dc1059ed8, 0x629a292a367cd507, + 0x9159015a3070dd17, 0x152fecd8f70e5939, + 0x67332667ffc00b31, 0x8eb44a8768581511, + 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4]; + +pub static H512: [u64; STATE_LEN] = [0x6a09e667f3bcc908, 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179]; + +pub static H512_TRUNC_224: [u64; STATE_LEN] = [0x8c3d37c819544da2, + 0x73e1996689dcd4d6, + 0x1dfab7ae32ff9c82, + 0x679dd514582f9fcf, + 0x0f6d2b697bd44da8, + 0x77e36f7304c48942, + 0x3f9d85a86a1d36c8, + 0x1112e6ad91d692a1]; + +pub static H512_TRUNC_256: [u64; STATE_LEN] = [0x22312194fc2bf72c, + 0x9f555fa3c84c64c2, + 0x2393b86b6f53b151, + 0x963877195940eabd, + 0x96283ee2a88effe3, + 0xbe5e1e2553863992, + 0x2b0199fc2c85b8aa, + 0x0eb72ddc81c52ca2]; diff --git a/third_party/rust/sha2-0.7.1/src/lib.rs b/third_party/rust/sha2-0.7.1/src/lib.rs new file mode 100644 index 000000000000..4f01d20bb7bd --- /dev/null +++ b/third_party/rust/sha2-0.7.1/src/lib.rs @@ -0,0 +1,85 @@ +//! An implementation of the SHA-2 cryptographic hash algorithms. +//! +//! There are 6 standard algorithms specified in the SHA-2 standard: +//! +//! * `Sha224`, which is the 32-bit `Sha256` algorithm with the result truncated +//! to 224 bits. +//! * `Sha256`, which is the 32-bit `Sha256` algorithm. +//! * `Sha384`, which is the 64-bit `Sha512` algorithm with the result truncated +//! to 384 bits. +//! * `Sha512`, which is the 64-bit `Sha512` algorithm. +//! * `Sha512Trunc224`, which is the 64-bit `Sha512` algorithm with the result +//! truncated to 224 bits. +//! * `Sha512Trunc256`, which is the 64-bit `Sha512` algorithm with the result +//! truncated to 256 bits. +//! +//! Algorithmically, there are only 2 core algorithms: `Sha256` and `Sha512`. +//! All other algorithms are just applications of these with different initial +//! hash values, and truncated to different digest bit lengths. +//! +//! # Usage +//! +//! An example of using `Sha256` is: +//! +//! ```rust +//! use sha2::{Sha256, Digest}; +//! +//! // create a Sha256 object +//! let mut hasher = Sha256::default(); +//! +//! // write input message +//! hasher.input(b"hello world"); +//! +//! // read hash digest and consume hasher +//! let output = hasher.result(); +//! +//! assert_eq!(output[..], [0xb9, 0x4d, 0x27, 0xb9, 0x93, 0x4d, 0x3e, 0x08, +//! 0xa5, 0x2e, 0x52, 0xd7, 0xda, 0x7d, 0xab, 0xfa, +//! 0xc4, 0x84, 0xef, 0xe3, 0x7a, 0x53, 0x80, 0xee, +//! 0x90, 0x88, 0xf7, 0xac, 0xe2, 0xef, 0xcd, 0xe9]); +//! ``` +//! +//! An example of using `Sha512` is: +//! +//! ```rust +//! use sha2::{Sha512, Digest}; +//! +//! // create a Sha512 object +//! let mut hasher = Sha512::default(); +//! +//! // write input message +//! hasher.input(b"hello world"); +//! +//! // read hash digest and consume hasher +//! let output = hasher.result(); +//! +//! assert_eq!(output[..], [0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, +//! 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02, 0xf2, 0xb4, +//! 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, +//! 0x9b, 0xcd, 0x3c, 0xa8, 0x6d, 0x4c, 0xd8, 0x6f, +//! 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, +//! 0x70, 0xda, 0x34, 0x25, 0x5b, 0x45, 0xb0, 0xcf, +//! 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d, +//! 0xc5, 0x54, 0x2e, 0x93, 0xae, 0x9c, 0xd7, 0x6f][..]); +//! ``` + +#![no_std] +extern crate byte_tools; +#[macro_use] +extern crate digest; +extern crate block_buffer; +extern crate fake_simd as simd; +#[cfg(feature = "asm")] +extern crate sha2_asm; + +mod consts; +#[cfg(not(feature = "asm"))] +mod sha256_utils; +#[cfg(not(feature = "asm"))] +mod sha512_utils; +mod sha256; +mod sha512; + +pub use digest::Digest; +pub use sha256::{Sha256, Sha224}; +pub use sha512::{Sha512, Sha384, Sha512Trunc224, Sha512Trunc256}; diff --git a/third_party/rust/sha2-0.7.1/src/sha256.rs b/third_party/rust/sha2-0.7.1/src/sha256.rs new file mode 100644 index 000000000000..6de9c6c29af9 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/src/sha256.rs @@ -0,0 +1,127 @@ +use digest; +use digest::generic_array::GenericArray; +use digest::generic_array::typenum::{U28, U32, U64}; +use block_buffer::BlockBuffer512; +use byte_tools::write_u32v_be; + +use consts::{STATE_LEN, H224, H256}; + +#[cfg(not(feature = "asm"))] +use sha256_utils::compress256; +#[cfg(feature = "asm")] +use sha2_asm::compress256; + +type BlockSize = U64; +pub type Block = [u8; 64]; + +/// A structure that represents that state of a digest computation for the +/// SHA-2 512 family of digest functions +#[derive(Clone)] +struct Engine256State { + h: [u32; 8], +} + +impl Engine256State { + fn new(h: &[u32; STATE_LEN]) -> Engine256State { Engine256State { h: *h } } + + pub fn process_block(&mut self, data: &Block) { + compress256(&mut self.h, data); + } +} + +/// A structure that keeps track of the state of the Sha-256 operation and +/// contains the logic necessary to perform the final calculations. +#[derive(Clone)] +struct Engine256 { + len: u64, + buffer: BlockBuffer512, + state: Engine256State, +} + +impl Engine256 { + fn new(h: &[u32; STATE_LEN]) -> Engine256 { + Engine256 { + len: 0, + buffer: Default::default(), + state: Engine256State::new(h), + } + } + + fn input(&mut self, input: &[u8]) { + // Assumes that input.len() can be converted to u64 without overflow + self.len += (input.len() as u64) << 3; + let self_state = &mut self.state; + self.buffer.input(input, |input| self_state.process_block(input)); + } + + fn finish(&mut self) { + let self_state = &mut self.state; + let l = self.len; + // TODO: replace with `len_padding_be` method + let l = if cfg!(target_endian = "little") { l.to_be() } else { l.to_le() }; + self.buffer.len_padding(l, |input| self_state.process_block(input)); + } +} + + +/// The SHA-256 hash algorithm with the SHA-256 initial hash value. +#[derive(Clone)] +pub struct Sha256 { + engine: Engine256, +} + +impl Default for Sha256 { + fn default() -> Self { Sha256 { engine: Engine256::new(&H256) } } +} + +impl digest::BlockInput for Sha256 { + type BlockSize = BlockSize; +} + +impl digest::Input for Sha256 { + fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +} + +impl digest::FixedOutput for Sha256 { + type OutputSize = U32; + + fn fixed_result(mut self) -> GenericArray { + self.engine.finish(); + let mut out = GenericArray::default(); + write_u32v_be(out.as_mut_slice(), &self.engine.state.h); + out + } +} + +/// The SHA-256 hash algorithm with the SHA-224 initial hash value. The result +/// is truncated to 224 bits. +#[derive(Clone)] +pub struct Sha224 { + engine: Engine256, +} + +impl Default for Sha224 { + fn default() -> Self { Sha224 { engine: Engine256::new(&H224) } } +} + +impl digest::BlockInput for Sha224 { + type BlockSize = BlockSize; +} + +impl digest::Input for Sha224 { + fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +} + +impl digest::FixedOutput for Sha224 { + type OutputSize = U28; + + fn fixed_result(mut self) -> GenericArray { + self.engine.finish(); + let mut out = GenericArray::default(); + write_u32v_be(out.as_mut_slice(), &self.engine.state.h[..7]); + out + } +} + +impl_opaque_debug!(Sha224); +impl_opaque_debug!(Sha256); diff --git a/third_party/rust/sha2-0.7.1/src/sha256_utils.rs b/third_party/rust/sha2-0.7.1/src/sha256_utils.rs new file mode 100644 index 000000000000..0a9d22b19362 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/src/sha256_utils.rs @@ -0,0 +1,267 @@ +#![cfg_attr(feature = "cargo-clippy", allow(many_single_char_names))] + +use simd::u32x4; +use consts::{BLOCK_LEN, K32X4}; +use byte_tools::{read_u32v_be}; +use sha256::Block; + +/// Not an intrinsic, but works like an unaligned load. +#[inline] +fn sha256load(v2: u32x4, v3: u32x4) -> u32x4 { + u32x4(v3.3, v2.0, v2.1, v2.2) +} + +/// Not an intrinsic, but useful for swapping vectors. +#[inline] +fn sha256swap(v0: u32x4) -> u32x4 { + u32x4(v0.2, v0.3, v0.0, v0.1) +} + +/// Emulates `llvm.x86.sha256msg1` intrinsic. +// #[inline] +fn sha256msg1(v0: u32x4, v1: u32x4) -> u32x4 { + + // sigma 0 on vectors + #[inline] + fn sigma0x4(x: u32x4) -> u32x4 { + ((x >> u32x4( 7, 7, 7, 7)) | (x << u32x4(25, 25, 25, 25))) ^ + ((x >> u32x4(18, 18, 18, 18)) | (x << u32x4(14, 14, 14, 14))) ^ + (x >> u32x4( 3, 3, 3, 3)) + } + + v0 + sigma0x4(sha256load(v0, v1)) +} + +/// Emulates `llvm.x86.sha256msg2` intrinsic. +// #[inline] +fn sha256msg2(v4: u32x4, v3: u32x4) -> u32x4 { + + macro_rules! sigma1 { + ($a:expr) => ($a.rotate_right(17) ^ $a.rotate_right(19) ^ ($a >> 10)) + } + + let u32x4(x3, x2, x1, x0) = v4; + let u32x4(w15, w14, _, _) = v3; + + let w16 = x0.wrapping_add(sigma1!(w14)); + let w17 = x1.wrapping_add(sigma1!(w15)); + let w18 = x2.wrapping_add(sigma1!(w16)); + let w19 = x3.wrapping_add(sigma1!(w17)); + + u32x4(w19, w18, w17, w16) +} + +/* +/// Performs 4 rounds of the SHA-256 message schedule update. +fn sha256_schedule_x4(v0: u32x4, v1: u32x4, v2: u32x4, v3: u32x4) -> u32x4 { + sha256msg2(sha256msg1(v0, v1) + sha256load(v2, v3), v3) +}*/ + +/// Emulates `llvm.x86.sha256rnds2` intrinsic. +// #[inline] +fn sha256_digest_round_x2(cdgh: u32x4, abef: u32x4, wk: u32x4) -> u32x4 { + + macro_rules! big_sigma0 { + ($a:expr) => (($a.rotate_right(2) ^ $a.rotate_right(13) ^ $a.rotate_right(22))) + } + macro_rules! big_sigma1 { + ($a:expr) => (($a.rotate_right(6) ^ $a.rotate_right(11) ^ $a.rotate_right(25))) + } + macro_rules! bool3ary_202 { + ($a:expr, $b:expr, $c:expr) => ($c ^ ($a & ($b ^ $c))) + } // Choose, MD5F, SHA1C + macro_rules! bool3ary_232 { + ($a:expr, $b:expr, $c:expr) => (($a & $b) ^ ($a & $c) ^ ($b & $c)) + } // Majority, SHA1M + + let u32x4(_, _, wk1, wk0) = wk; + let u32x4(a0, b0, e0, f0) = abef; + let u32x4(c0, d0, g0, h0) = cdgh; + + // a round + let x0 = big_sigma1!(e0) + .wrapping_add(bool3ary_202!(e0, f0, g0)) + .wrapping_add(wk0) + .wrapping_add(h0); + let y0 = big_sigma0!(a0).wrapping_add(bool3ary_232!(a0, b0, c0)); + let (a1, b1, c1, d1, e1, f1, g1, h1) = + (x0.wrapping_add(y0), a0, b0, c0, x0.wrapping_add(d0), e0, f0, g0); + + // a round + let x1 = big_sigma1!(e1) + .wrapping_add(bool3ary_202!(e1, f1, g1)) + .wrapping_add(wk1) + .wrapping_add(h1); + let y1 = big_sigma0!(a1).wrapping_add(bool3ary_232!(a1, b1, c1)); + let (a2, b2, _, _, e2, f2, _, _) = + (x1.wrapping_add(y1), a1, b1, c1, x1.wrapping_add(d1), e1, f1, g1); + + u32x4(a2, b2, e2, f2) +} + +/// Process a block with the SHA-256 algorithm. +fn sha256_digest_block_u32(state: &mut [u32; 8], block: &[u32; 16]) { + let k = &K32X4; + + macro_rules! schedule { + ($v0:expr, $v1:expr, $v2:expr, $v3:expr) => ( + sha256msg2(sha256msg1($v0, $v1) + sha256load($v2, $v3), $v3) + ) + } + + macro_rules! rounds4 { + ($abef:ident, $cdgh:ident, $rest:expr) => { + { + $cdgh = sha256_digest_round_x2($cdgh, $abef, $rest); + $abef = sha256_digest_round_x2($abef, $cdgh, sha256swap($rest)); + } + } + } + + let mut abef = u32x4(state[0], state[1], state[4], state[5]); + let mut cdgh = u32x4(state[2], state[3], state[6], state[7]); + + // Rounds 0..64 + let mut w0 = u32x4(block[3], block[2], block[1], block[0]); + rounds4!(abef, cdgh, k[0] + w0); + let mut w1 = u32x4(block[7], block[6], block[5], block[4]); + rounds4!(abef, cdgh, k[1] + w1); + let mut w2 = u32x4(block[11], block[10], block[9], block[8]); + rounds4!(abef, cdgh, k[2] + w2); + let mut w3 = u32x4(block[15], block[14], block[13], block[12]); + rounds4!(abef, cdgh, k[3] + w3); + let mut w4 = schedule!(w0, w1, w2, w3); + rounds4!(abef, cdgh, k[4] + w4); + w0 = schedule!(w1, w2, w3, w4); + rounds4!(abef, cdgh, k[5] + w0); + w1 = schedule!(w2, w3, w4, w0); + rounds4!(abef, cdgh, k[6] + w1); + w2 = schedule!(w3, w4, w0, w1); + rounds4!(abef, cdgh, k[7] + w2); + w3 = schedule!(w4, w0, w1, w2); + rounds4!(abef, cdgh, k[8] + w3); + w4 = schedule!(w0, w1, w2, w3); + rounds4!(abef, cdgh, k[9] + w4); + w0 = schedule!(w1, w2, w3, w4); + rounds4!(abef, cdgh, k[10] + w0); + w1 = schedule!(w2, w3, w4, w0); + rounds4!(abef, cdgh, k[11] + w1); + w2 = schedule!(w3, w4, w0, w1); + rounds4!(abef, cdgh, k[12] + w2); + w3 = schedule!(w4, w0, w1, w2); + rounds4!(abef, cdgh, k[13] + w3); + w4 = schedule!(w0, w1, w2, w3); + rounds4!(abef, cdgh, k[14] + w4); + w0 = schedule!(w1, w2, w3, w4); + rounds4!(abef, cdgh, k[15] + w0); + + let u32x4(a, b, e, f) = abef; + let u32x4(c, d, g, h) = cdgh; + + state[0] = state[0].wrapping_add(a); + state[1] = state[1].wrapping_add(b); + state[2] = state[2].wrapping_add(c); + state[3] = state[3].wrapping_add(d); + state[4] = state[4].wrapping_add(e); + state[5] = state[5].wrapping_add(f); + state[6] = state[6].wrapping_add(g); + state[7] = state[7].wrapping_add(h); +} + +/// Process a block with the SHA-256 algorithm. (See more...) +/// +/// Internally, this uses functions which resemble the new Intel SHA instruction +/// sets, and so it's data locality properties may improve performance. However, +/// to benefit the most from this implementation, replace these functions with +/// x86 intrinsics to get a possible speed boost. +/// +/// # Implementation +/// +/// The `Sha256` algorithm is implemented with functions that resemble the new +/// Intel SHA instruction set extensions. These intructions fall into two +/// categories: message schedule calculation, and the message block 64-round +/// digest calculation. The schedule-related instructions allow 4 rounds to be +/// calculated as: +/// +/// ```ignore +/// use std::simd::u32x4; +/// use self::crypto::sha2::{ +/// sha256msg1, +/// sha256msg2, +/// sha256load +/// }; +/// +/// fn schedule4_data(work: &mut [u32x4], w: &[u32]) { +/// +/// // this is to illustrate the data order +/// work[0] = u32x4(w[3], w[2], w[1], w[0]); +/// work[1] = u32x4(w[7], w[6], w[5], w[4]); +/// work[2] = u32x4(w[11], w[10], w[9], w[8]); +/// work[3] = u32x4(w[15], w[14], w[13], w[12]); +/// } +/// +/// fn schedule4_work(work: &mut [u32x4], t: usize) { +/// +/// // this is the core expression +/// work[t] = sha256msg2(sha256msg1(work[t - 4], work[t - 3]) + +/// sha256load(work[t - 2], work[t - 1]), +/// work[t - 1]) +/// } +/// ``` +/// +/// instead of 4 rounds of: +/// +/// ```ignore +/// fn schedule_work(w: &mut [u32], t: usize) { +/// w[t] = sigma1!(w[t - 2]) + w[t - 7] + sigma0!(w[t - 15]) + w[t - 16]; +/// } +/// ``` +/// +/// and the digest-related instructions allow 4 rounds to be calculated as: +/// +/// ```ignore +/// use std::simd::u32x4; +/// use self::crypto::sha2::{K32X4, +/// sha256rnds2, +/// sha256swap +/// }; +/// +/// fn rounds4(state: &mut [u32; 8], work: &mut [u32x4], t: usize) { +/// let [a, b, c, d, e, f, g, h]: [u32; 8] = *state; +/// +/// // this is to illustrate the data order +/// let mut abef = u32x4(a, b, e, f); +/// let mut cdgh = u32x4(c, d, g, h); +/// let temp = K32X4[t] + work[t]; +/// +/// // this is the core expression +/// cdgh = sha256rnds2(cdgh, abef, temp); +/// abef = sha256rnds2(abef, cdgh, sha256swap(temp)); +/// +/// *state = [abef.0, abef.1, cdgh.0, cdgh.1, +/// abef.2, abef.3, cdgh.2, cdgh.3]; +/// } +/// ``` +/// +/// instead of 4 rounds of: +/// +/// ```ignore +/// fn round(state: &mut [u32; 8], w: &mut [u32], t: usize) { +/// let [a, b, c, mut d, e, f, g, mut h]: [u32; 8] = *state; +/// +/// h += big_sigma1!(e) + choose!(e, f, g) + K32[t] + w[t]; d += h; +/// h += big_sigma0!(a) + majority!(a, b, c); +/// +/// *state = [h, a, b, c, d, e, f, g]; +/// } +/// ``` +/// +/// **NOTE**: It is important to note, however, that these instructions are not +/// implemented by any CPU (at the time of this writing), and so they are +/// emulated in this library until the instructions become more common, and gain +/// support in LLVM (and GCC, etc.). +pub fn compress256(state: &mut [u32; 8], block: &Block) { + let mut block_u32 = [0u32; BLOCK_LEN]; + read_u32v_be(&mut block_u32[..], block); + sha256_digest_block_u32(state, &block_u32); +} diff --git a/third_party/rust/sha2-0.7.1/src/sha512.rs b/third_party/rust/sha2-0.7.1/src/sha512.rs new file mode 100644 index 000000000000..b22cfeba92df --- /dev/null +++ b/third_party/rust/sha2-0.7.1/src/sha512.rs @@ -0,0 +1,209 @@ +use digest; +use digest::generic_array::GenericArray; +use digest::generic_array::typenum::{U28, U32, U48, U64, U128}; +use block_buffer::BlockBuffer1024; +use byte_tools::{write_u64v_be, write_u32_be}; + +use consts::{STATE_LEN, H384, H512, H512_TRUNC_224, H512_TRUNC_256}; + +#[cfg(not(feature = "asm"))] +use sha512_utils::compress512; +#[cfg(feature = "asm")] +use sha2_asm::compress512; + +type BlockSize = U128; +pub type Block = [u8; 128]; + +/// A structure that represents that state of a digest computation for the +/// SHA-2 512 family of digest functions +#[derive(Clone)] +struct Engine512State { + h: [u64; 8], +} + +impl Engine512State { + fn new(h: &[u64; 8]) -> Engine512State { Engine512State { h: *h } } + + pub fn process_block(&mut self, data: &Block) { + compress512(&mut self.h, data); + } +} + +/// A structure that keeps track of the state of the Sha-512 operation and +/// contains the logic necessary to perform the final calculations. +#[derive(Clone)] +struct Engine512 { + len: (u64, u64), // TODO: replace with u128 on stabilization + buffer: BlockBuffer1024, + state: Engine512State, +} + +impl Engine512 { + fn new(h: &[u64; STATE_LEN]) -> Engine512 { + Engine512 { + len: (0, 0), + buffer: Default::default(), + state: Engine512State::new(h), + } + } + + fn input(&mut self, input: &[u8]) { + let (res, over) = self.len.1.overflowing_add((input.len() as u64) << 3); + self.len.1 = res; + if over { self.len.0 += 1; } + let self_state = &mut self.state; + self.buffer.input(input, |d| self_state.process_block(d)); + } + + fn finish(&mut self) { + let self_state = &mut self.state; + let (mut hi, mut lo) = self.len; + // TODO: change `len_padding_u128` to use BE + if cfg!(target_endian = "little") { + hi = hi.to_be(); + lo = lo.to_be(); + } else { + hi = hi.to_le(); + lo = lo.to_le(); + }; + self.buffer.len_padding_u128(hi, lo, |d| self_state.process_block(d)); + } +} + + +/// The SHA-512 hash algorithm with the SHA-512 initial hash value. +#[derive(Clone)] +pub struct Sha512 { + engine: Engine512, +} + +impl Default for Sha512 { + fn default() -> Self { Sha512 { engine: Engine512::new(&H512) } } +} + +impl digest::BlockInput for Sha512 { + type BlockSize = BlockSize; +} + +impl digest::Input for Sha512 { + fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +} + +impl digest::FixedOutput for Sha512 { + type OutputSize = U64; + + fn fixed_result(mut self) -> GenericArray { + self.engine.finish(); + + let mut out = GenericArray::default(); + write_u64v_be(out.as_mut_slice(), &self.engine.state.h[..]); + out + } +} + + + +/// The SHA-512 hash algorithm with the SHA-384 initial hash value. The result +/// is truncated to 384 bits. +#[derive(Clone)] +pub struct Sha384 { + engine: Engine512, +} + +impl Default for Sha384 { + fn default() -> Self { Sha384 { engine: Engine512::new(&H384) } } +} + +impl digest::BlockInput for Sha384 { + type BlockSize = BlockSize; +} + +impl digest::Input for Sha384 { + fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +} + +impl digest::FixedOutput for Sha384 { + type OutputSize = U48; + + fn fixed_result(mut self) -> GenericArray { + self.engine.finish(); + + let mut out = GenericArray::default(); + write_u64v_be(out.as_mut_slice(), &self.engine.state.h[..6]); + out + } +} + + + +/// The SHA-512 hash algorithm with the SHA-512/256 initial hash value. The +/// result is truncated to 256 bits. +#[derive(Clone)] +pub struct Sha512Trunc256 { + engine: Engine512, +} + +impl Default for Sha512Trunc256 { + fn default() -> Self { + Sha512Trunc256 { engine: Engine512::new(&H512_TRUNC_256) } + } +} + +impl digest::BlockInput for Sha512Trunc256 { + type BlockSize = BlockSize; +} + +impl digest::Input for Sha512Trunc256 { + fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +} + +impl digest::FixedOutput for Sha512Trunc256 { + type OutputSize = U32; + + fn fixed_result(mut self) -> GenericArray { + self.engine.finish(); + + let mut out = GenericArray::default(); + write_u64v_be(out.as_mut_slice(), &self.engine.state.h[..4]); + out + } +} + +/// The SHA-512 hash algorithm with the SHA-512/224 initial hash value. +/// The result is truncated to 224 bits. +#[derive(Clone)] +pub struct Sha512Trunc224 { + engine: Engine512, +} + +impl Default for Sha512Trunc224 { + fn default() -> Self { + Sha512Trunc224 { engine: Engine512::new(&H512_TRUNC_224) } + } +} + +impl digest::BlockInput for Sha512Trunc224 { + type BlockSize = BlockSize; +} + +impl digest::Input for Sha512Trunc224 { + fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +} + +impl digest::FixedOutput for Sha512Trunc224 { + type OutputSize = U28; + + fn fixed_result(mut self) -> GenericArray { + self.engine.finish(); + + let mut out = GenericArray::default(); + write_u64v_be(&mut out[..24], &self.engine.state.h[..3]); + write_u32_be(&mut out[24..28], (self.engine.state.h[3] >> 32) as u32); + out + } +} + +impl_opaque_debug!(Sha384); +impl_opaque_debug!(Sha512); +impl_opaque_debug!(Sha512Trunc224); +impl_opaque_debug!(Sha512Trunc256); diff --git a/third_party/rust/sha2-0.7.1/src/sha512_utils.rs b/third_party/rust/sha2-0.7.1/src/sha512_utils.rs new file mode 100644 index 000000000000..0ab6ad3077c0 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/src/sha512_utils.rs @@ -0,0 +1,287 @@ +#![cfg_attr(feature = "cargo-clippy", allow(many_single_char_names))] + +use simd::u64x2; +use consts::{BLOCK_LEN, K64X2}; +use byte_tools::{read_u64v_be}; +use sha512::Block; + +/// Not an intrinsic, but works like an unaligned load. +#[inline] +fn sha512load(v0: u64x2, v1: u64x2) -> u64x2 { + u64x2(v1.1, v0.0) +} + +/// Performs 2 rounds of the SHA-512 message schedule update. +pub fn sha512_schedule_x2(v0: u64x2, v1: u64x2, v4to5: u64x2, v7: u64x2) + -> u64x2 { + + // sigma 0 + fn sigma0(x: u64) -> u64 { + ((x << 63) | (x >> 1)) ^ ((x << 56) | (x >> 8)) ^ (x >> 7) + } + + // sigma 1 + fn sigma1(x: u64) -> u64 { + ((x << 45) | (x >> 19)) ^ ((x << 3) | (x >> 61)) ^ (x >> 6) + } + + let u64x2(w1, w0) = v0; + let u64x2(_, w2) = v1; + let u64x2(w10, w9) = v4to5; + let u64x2(w15, w14) = v7; + + let w16 = + sigma1(w14).wrapping_add(w9).wrapping_add(sigma0(w1)).wrapping_add(w0); + let w17 = + sigma1(w15).wrapping_add(w10).wrapping_add(sigma0(w2)).wrapping_add(w1); + + u64x2(w17, w16) +} + +/// Performs one round of the SHA-512 message block digest. +pub fn sha512_digest_round(ae: u64x2, bf: u64x2, cg: u64x2, dh: u64x2, + wk0: u64) + -> u64x2 { + + macro_rules! big_sigma0 { + ($a:expr) => (($a.rotate_right(28) ^ $a.rotate_right(34) ^ $a.rotate_right(39))) + } + macro_rules! big_sigma1 { + ($a:expr) => (($a.rotate_right(14) ^ $a.rotate_right(18) ^ $a.rotate_right(41))) + } + macro_rules! bool3ary_202 { + ($a:expr, $b:expr, $c:expr) => ($c ^ ($a & ($b ^ $c))) + } // Choose, MD5F, SHA1C + macro_rules! bool3ary_232 { + ($a:expr, $b:expr, $c:expr) => (($a & $b) ^ ($a & $c) ^ ($b & $c)) + } // Majority, SHA1M + + let u64x2(a0, e0) = ae; + let u64x2(b0, f0) = bf; + let u64x2(c0, g0) = cg; + let u64x2(d0, h0) = dh; + + // a round + let x0 = big_sigma1!(e0) + .wrapping_add(bool3ary_202!(e0, f0, g0)) + .wrapping_add(wk0) + .wrapping_add(h0); + let y0 = big_sigma0!(a0).wrapping_add(bool3ary_232!(a0, b0, c0)); + let (a1, _, _, _, e1, _, _, _) = + (x0.wrapping_add(y0), a0, b0, c0, x0.wrapping_add(d0), e0, f0, g0); + + u64x2(a1, e1) +} + +/// Process a block with the SHA-512 algorithm. +pub fn sha512_digest_block_u64(state: &mut [u64; 8], block: &[u64; 16]) { + let k = &K64X2; + + macro_rules! schedule { + ($v0:expr, $v1:expr, $v4:expr, $v5:expr, $v7:expr) => ( + sha512_schedule_x2($v0, $v1, sha512load($v4, $v5), $v7) + ) + } + + macro_rules! rounds4 { + ($ae:ident, $bf:ident, $cg:ident, $dh:ident, $wk0:expr, $wk1:expr) => { + { + let u64x2(u, t) = $wk0; + let u64x2(w, v) = $wk1; + + $dh = sha512_digest_round($ae, $bf, $cg, $dh, t); + $cg = sha512_digest_round($dh, $ae, $bf, $cg, u); + $bf = sha512_digest_round($cg, $dh, $ae, $bf, v); + $ae = sha512_digest_round($bf, $cg, $dh, $ae, w); + } + } + } + + let mut ae = u64x2(state[0], state[4]); + let mut bf = u64x2(state[1], state[5]); + let mut cg = u64x2(state[2], state[6]); + let mut dh = u64x2(state[3], state[7]); + + // Rounds 0..20 + let (mut w1, mut w0) = (u64x2(block[3], block[2]), + u64x2(block[1], block[0])); + rounds4!(ae, bf, cg, dh, k[0] + w0, k[1] + w1); + let (mut w3, mut w2) = (u64x2(block[7], block[6]), + u64x2(block[5], block[4])); + rounds4!(ae, bf, cg, dh, k[2] + w2, k[3] + w3); + let (mut w5, mut w4) = (u64x2(block[11], block[10]), + u64x2(block[9], block[8])); + rounds4!(ae, bf, cg, dh, k[4] + w4, k[5] + w5); + let (mut w7, mut w6) = (u64x2(block[15], block[14]), + u64x2(block[13], block[12])); + rounds4!(ae, bf, cg, dh, k[6] + w6, k[7] + w7); + let mut w8 = schedule!(w0, w1, w4, w5, w7); + let mut w9 = schedule!(w1, w2, w5, w6, w8); + rounds4!(ae, bf, cg, dh, k[8] + w8, k[9] + w9); + + // Rounds 20..40 + w0 = schedule!(w2, w3, w6, w7, w9); + w1 = schedule!(w3, w4, w7, w8, w0); + rounds4!(ae, bf, cg, dh, k[10] + w0, k[11] + w1); + w2 = schedule!(w4, w5, w8, w9, w1); + w3 = schedule!(w5, w6, w9, w0, w2); + rounds4!(ae, bf, cg, dh, k[12] + w2, k[13] + w3); + w4 = schedule!(w6, w7, w0, w1, w3); + w5 = schedule!(w7, w8, w1, w2, w4); + rounds4!(ae, bf, cg, dh, k[14] + w4, k[15] + w5); + w6 = schedule!(w8, w9, w2, w3, w5); + w7 = schedule!(w9, w0, w3, w4, w6); + rounds4!(ae, bf, cg, dh, k[16] + w6, k[17] + w7); + w8 = schedule!(w0, w1, w4, w5, w7); + w9 = schedule!(w1, w2, w5, w6, w8); + rounds4!(ae, bf, cg, dh, k[18] + w8, k[19] + w9); + + // Rounds 40..60 + w0 = schedule!(w2, w3, w6, w7, w9); + w1 = schedule!(w3, w4, w7, w8, w0); + rounds4!(ae, bf, cg, dh, k[20] + w0, k[21] + w1); + w2 = schedule!(w4, w5, w8, w9, w1); + w3 = schedule!(w5, w6, w9, w0, w2); + rounds4!(ae, bf, cg, dh, k[22] + w2, k[23] + w3); + w4 = schedule!(w6, w7, w0, w1, w3); + w5 = schedule!(w7, w8, w1, w2, w4); + rounds4!(ae, bf, cg, dh, k[24] + w4, k[25] + w5); + w6 = schedule!(w8, w9, w2, w3, w5); + w7 = schedule!(w9, w0, w3, w4, w6); + rounds4!(ae, bf, cg, dh, k[26] + w6, k[27] + w7); + w8 = schedule!(w0, w1, w4, w5, w7); + w9 = schedule!(w1, w2, w5, w6, w8); + rounds4!(ae, bf, cg, dh, k[28] + w8, k[29] + w9); + + // Rounds 60..80 + w0 = schedule!(w2, w3, w6, w7, w9); + w1 = schedule!(w3, w4, w7, w8, w0); + rounds4!(ae, bf, cg, dh, k[30] + w0, k[31] + w1); + w2 = schedule!(w4, w5, w8, w9, w1); + w3 = schedule!(w5, w6, w9, w0, w2); + rounds4!(ae, bf, cg, dh, k[32] + w2, k[33] + w3); + w4 = schedule!(w6, w7, w0, w1, w3); + w5 = schedule!(w7, w8, w1, w2, w4); + rounds4!(ae, bf, cg, dh, k[34] + w4, k[35] + w5); + w6 = schedule!(w8, w9, w2, w3, w5); + w7 = schedule!(w9, w0, w3, w4, w6); + rounds4!(ae, bf, cg, dh, k[36] + w6, k[37] + w7); + w8 = schedule!(w0, w1, w4, w5, w7); + w9 = schedule!(w1, w2, w5, w6, w8); + rounds4!(ae, bf, cg, dh, k[38] + w8, k[39] + w9); + + let u64x2(a, e) = ae; + let u64x2(b, f) = bf; + let u64x2(c, g) = cg; + let u64x2(d, h) = dh; + + state[0] = state[0].wrapping_add(a); + state[1] = state[1].wrapping_add(b); + state[2] = state[2].wrapping_add(c); + state[3] = state[3].wrapping_add(d); + state[4] = state[4].wrapping_add(e); + state[5] = state[5].wrapping_add(f); + state[6] = state[6].wrapping_add(g); + state[7] = state[7].wrapping_add(h); +} + +/// Process a block with the SHA-512 algorithm. (See more...) +/// +/// Internally, this uses functions that resemble the new Intel SHA +/// instruction set extensions, but since no architecture seems to +/// have any designs, these may not be the final designs if and/or when +/// there are instruction set extensions with SHA-512. So to summarize: +/// SHA-1 and SHA-256 are being implemented in hardware soon (at the time +/// of this writing), but it doesn't look like SHA-512 will be hardware +/// accelerated any time soon. +/// +/// # Implementation +/// +/// These functions fall into two categories: message schedule calculation, and +/// the message block 64-round digest calculation. The schedule-related +/// functions allow 4 rounds to be calculated as: +/// +/// ```ignore +/// use std::simd::u64x2; +/// use self::crypto::sha2::{ +/// sha512msg, +/// sha512load +/// }; +/// +/// fn schedule4_data(work: &mut [u64x2], w: &[u64]) { +/// +/// // this is to illustrate the data order +/// work[0] = u64x2(w[1], w[0]); +/// work[1] = u64x2(w[3], w[2]); +/// work[2] = u64x2(w[5], w[4]); +/// work[3] = u64x2(w[7], w[6]); +/// work[4] = u64x2(w[9], w[8]); +/// work[5] = u64x2(w[11], w[10]); +/// work[6] = u64x2(w[13], w[12]); +/// work[7] = u64x2(w[15], w[14]); +/// } +/// +/// fn schedule4_work(work: &mut [u64x2], t: usize) { +/// +/// // this is the core expression +/// work[t] = sha512msg(work[t - 8], +/// work[t - 7], +/// sha512load(work[t - 4], work[t - 3]), +/// work[t - 1]); +/// } +/// ``` +/// +/// instead of 4 rounds of: +/// +/// ```ignore +/// fn schedule_work(w: &mut [u64], t: usize) { +/// w[t] = sigma1!(w[t - 2]) + w[t - 7] + sigma0!(w[t - 15]) + w[t - 16]; +/// } +/// ``` +/// +/// and the digest-related functions allow 4 rounds to be calculated as: +/// +/// ```ignore +/// use std::simd::u64x2; +/// use self::crypto::sha2::{K64X2, sha512rnd}; +/// +/// fn rounds4(state: &mut [u64; 8], work: &mut [u64x2], t: usize) { +/// let [a, b, c, d, e, f, g, h]: [u64; 8] = *state; +/// +/// // this is to illustrate the data order +/// let mut ae = u64x2(a, e); +/// let mut bf = u64x2(b, f); +/// let mut cg = u64x2(c, g); +/// let mut dh = u64x2(d, h); +/// let u64x2(w1, w0) = K64X2[2*t] + work[2*t]; +/// let u64x2(w3, w2) = K64X2[2*t + 1] + work[2*t + 1]; +/// +/// // this is the core expression +/// dh = sha512rnd(ae, bf, cg, dh, w0); +/// cg = sha512rnd(dh, ae, bf, cg, w1); +/// bf = sha512rnd(cg, dh, ae, bf, w2); +/// ae = sha512rnd(bf, cg, dh, ae, w3); +/// +/// *state = [ae.0, bf.0, cg.0, dh.0, +/// ae.1, bf.1, cg.1, dh.1]; +/// } +/// ``` +/// +/// instead of 4 rounds of: +/// +/// ```ignore +/// fn round(state: &mut [u64; 8], w: &mut [u64], t: usize) { +/// let [a, b, c, mut d, e, f, g, mut h]: [u64; 8] = *state; +/// +/// h += big_sigma1!(e) + choose!(e, f, g) + K64[t] + w[t]; d += h; +/// h += big_sigma0!(a) + majority!(a, b, c); +/// +/// *state = [h, a, b, c, d, e, f, g]; +/// } +/// ``` +/// +pub fn compress512(state: &mut [u64; 8], block: &Block) { + let mut block_u64 = [0u64; BLOCK_LEN]; + read_u64v_be(&mut block_u64[..], block); + sha512_digest_block_u64(state, &block_u64); +} diff --git a/third_party/rust/sha2/tests/data/sha224/test1.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha224/test1.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha224/test1.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha224/test1.input.bin diff --git a/third_party/rust/sha2/tests/data/sha224/test1.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha224/test1.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha224/test1.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha224/test1.output.bin diff --git a/third_party/rust/sha2/tests/data/sha224/test2.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha224/test2.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha224/test2.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha224/test2.input.bin diff --git a/third_party/rust/sha2/tests/data/sha224/test2.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha224/test2.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha224/test2.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha224/test2.output.bin diff --git a/third_party/rust/sha2/tests/data/sha224/test3.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha224/test3.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha224/test3.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha224/test3.input.bin diff --git a/third_party/rust/sha2/tests/data/sha224/test3.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha224/test3.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha224/test3.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha224/test3.output.bin diff --git a/third_party/rust/sha2/tests/data/sha256/one_million_a.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha256/one_million_a.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha256/one_million_a.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha256/one_million_a.output.bin diff --git a/third_party/rust/sha2/tests/data/sha256/test1.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha256/test1.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha256/test1.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha256/test1.input.bin diff --git a/third_party/rust/sha2/tests/data/sha256/test1.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha256/test1.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha256/test1.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha256/test1.output.bin diff --git a/third_party/rust/sha2/tests/data/sha256/test2.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha256/test2.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha256/test2.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha256/test2.input.bin diff --git a/third_party/rust/sha2/tests/data/sha256/test2.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha256/test2.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha256/test2.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha256/test2.output.bin diff --git a/third_party/rust/sha2/tests/data/sha256/test3.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha256/test3.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha256/test3.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha256/test3.input.bin diff --git a/third_party/rust/sha2/tests/data/sha256/test3.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha256/test3.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha256/test3.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha256/test3.output.bin diff --git a/third_party/rust/sha2/tests/data/sha384/test1.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha384/test1.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha384/test1.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha384/test1.input.bin diff --git a/third_party/rust/sha2/tests/data/sha384/test1.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha384/test1.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha384/test1.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha384/test1.output.bin diff --git a/third_party/rust/sha2/tests/data/sha384/test2.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha384/test2.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha384/test2.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha384/test2.input.bin diff --git a/third_party/rust/sha2/tests/data/sha384/test2.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha384/test2.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha384/test2.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha384/test2.output.bin diff --git a/third_party/rust/sha2/tests/data/sha384/test3.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha384/test3.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha384/test3.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha384/test3.input.bin diff --git a/third_party/rust/sha2/tests/data/sha384/test3.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha384/test3.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha384/test3.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha384/test3.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512/one_million_a.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512/one_million_a.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512/one_million_a.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512/one_million_a.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512/test1.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512/test1.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512/test1.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512/test1.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512/test1.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512/test1.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512/test1.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512/test1.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512/test2.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512/test2.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512/test2.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512/test2.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512/test2.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512/test2.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512/test2.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512/test2.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512/test3.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512/test3.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512/test3.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512/test3.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512/test3.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512/test3.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512/test3.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512/test3.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512_224/test1.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_224/test1.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_224/test1.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_224/test1.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512_224/test1.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_224/test1.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_224/test1.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_224/test1.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512_224/test2.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_224/test2.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_224/test2.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_224/test2.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512_224/test2.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_224/test2.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_224/test2.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_224/test2.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512_224/test3.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_224/test3.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_224/test3.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_224/test3.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512_224/test3.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_224/test3.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_224/test3.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_224/test3.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512_256/test1.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_256/test1.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_256/test1.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_256/test1.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512_256/test1.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_256/test1.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_256/test1.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_256/test1.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512_256/test2.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_256/test2.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_256/test2.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_256/test2.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512_256/test2.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_256/test2.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_256/test2.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_256/test2.output.bin diff --git a/third_party/rust/sha2/tests/data/sha512_256/test3.input.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_256/test3.input.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_256/test3.input.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_256/test3.input.bin diff --git a/third_party/rust/sha2/tests/data/sha512_256/test3.output.bin b/third_party/rust/sha2-0.7.1/tests/data/sha512_256/test3.output.bin similarity index 100% rename from third_party/rust/sha2/tests/data/sha512_256/test3.output.bin rename to third_party/rust/sha2-0.7.1/tests/data/sha512_256/test3.output.bin diff --git a/third_party/rust/sha2-0.7.1/tests/lib.rs b/third_party/rust/sha2-0.7.1/tests/lib.rs new file mode 100644 index 000000000000..e386fcc46105 --- /dev/null +++ b/third_party/rust/sha2-0.7.1/tests/lib.rs @@ -0,0 +1,54 @@ +#![no_std] +#[macro_use] +extern crate digest; +extern crate sha2; + +use digest::dev::{Test, main_test, one_million_a}; + +#[test] +fn sha2_224_main() { + let tests = new_tests!("sha224/test1", "sha224/test2", "sha224/test3"); + main_test::(&tests); +} + +#[test] +fn sha2_256_main() { + let tests = new_tests!("sha256/test1", "sha256/test2", "sha256/test3"); + main_test::(&tests); +} + +#[test] +fn sha2_384_main() { + let tests = new_tests!("sha384/test1", "sha384/test2", "sha384/test3"); + main_test::(&tests); +} + +#[test] +fn sha2_512_main() { + let tests = new_tests!("sha512/test1", "sha512/test2", "sha512/test3"); + main_test::(&tests); +} + +#[test] +fn sha2_512_trunc_256_main() { + let tests = new_tests!("sha512_256/test1", "sha512_256/test2", "sha512_256/test3"); + main_test::(&tests); +} + +#[test] +fn sha2_512_trunc_224_main() { + let tests = new_tests!("sha512_224/test1", "sha512_224/test2", "sha512_224/test3"); + main_test::(&tests); +} + +#[test] +fn sha2_256_1million_a() { + let output = include_bytes!("data/sha256/one_million_a.output.bin"); + one_million_a::(output); +} + +#[test] +fn sha2_512_1million_a() { + let output = include_bytes!("data/sha512/one_million_a.output.bin"); + one_million_a::(output); +} \ No newline at end of file diff --git a/third_party/rust/sha2/.cargo-checksum.json b/third_party/rust/sha2/.cargo-checksum.json index 6144e702f3d3..91c269be8bac 100644 --- a/third_party/rust/sha2/.cargo-checksum.json +++ b/third_party/rust/sha2/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"1edde1679db6070037fff3fe48cfacc14ac1ce9fd59142a629ec948ba272158b","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"b4eb00df6e2a4d22518fcaa6a2b4646f249b3a3c9814509b22bd2091f1392ff1","benches/sha256.rs":"221b7fc2f43cb57094adfdf3f422d24fead8c87653d3fb36b764f103542d7cef","benches/sha512.rs":"0455cf7e63c3145eb109f860e81a0c1af504b61456e8d2372ac5e158e95c1b30","examples/sha256sum.rs":"82f5c111cfc3c6db386b2e1ed300e0f45cd781d6b0f291537e3db9f390dfb79b","examples/sha512sum.rs":"ba7690db22ff7ac7f5884bde6896a54ac6a82f05802e118d2f8c5458198687a6","src/consts.rs":"06e7bae76155291d1f896b72b625500859fbcfb80ee948ab3919620c96320610","src/lib.rs":"05c31c49cd10f421028acb37c52fcffec6b6006e47274a212e906c9fd7c62199","src/sha256.rs":"17e6efc69c3910b05116e44aabef22b2b770b4d42fba53465ba07dee5f211eab","src/sha256_utils.rs":"4d764643ee34a5387d4deea26e12ad6d8d51480fe3e3c502dcbe97bb8b3148a0","src/sha512.rs":"ccc6679ddb21d11abefd940e119ae78eee8214d44446ff7186797feed70d2e45","src/sha512_utils.rs":"0b67350b0f796981290e152a1020275527d6e0ed902328097b1ee1c7dfaedf5c","tests/data/sha224/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha224/test1.output.bin":"70e01c74bb4c4b3e5b2dc7cba0694f9bc78e220e89e1f133f62c38781ebd1378","tests/data/sha224/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha224/test2.output.bin":"7cfed1501838fd337c201c54ab622bf2337edded6aac84a978cff9f1db267c08","tests/data/sha224/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha224/test3.output.bin":"3fea089ea073f5b90609aa1bcef080c3af270e3c57fc142f6aaec9a6e041f347","tests/data/sha256/one_million_a.output.bin":"80d1189477563e1b5206b2749f1afe4807e5705e8bd77887a60187a712156688","tests/data/sha256/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha256/test1.output.bin":"5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456","tests/data/sha256/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha256/test2.output.bin":"6d37795021e544d82b41850edf7aabab9a0ebe274e54a519840c4666f35b3937","tests/data/sha256/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha256/test3.output.bin":"a51a910ecba8a599555b32133bf1829455d55fe576677b49cb561d874077385c","tests/data/sha384/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha384/test1.output.bin":"4800fbfc4566eb02d1727a4b1c949ccbc7535c216a0766564c199308631b5dd6","tests/data/sha384/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha384/test2.output.bin":"0743eb48e2913c5d5d963ec13a4515ec2f9ca6ffe72e91a935871b2bff2103a0","tests/data/sha384/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha384/test3.output.bin":"b3917c6fb1f65c2b91fdbfe3a484f171949f27f3980796f4ae1b31ec9841d0f6","tests/data/sha512/one_million_a.output.bin":"a872d736156b28b7784fcc124cfb9993ed31707f1754a0a448d26bf84f5cc7f5","tests/data/sha512/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha512/test1.output.bin":"001d686db504e20c792eaa07fe09224a45ff328e24a80072d04d16abc5c2b5d2","tests/data/sha512/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha512/test2.output.bin":"372efde43fa80632b3a582d8908909f25d628928242d44531e7bef0012f6c811","tests/data/sha512/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha512/test3.output.bin":"53e379e5e4d9afd6229cb1bbb8698a59e311ed6c7111c2f8239be08f081b88d0","tests/data/sha512_224/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha512_224/test1.output.bin":"480be8cbde48b8416d5576ed5909ae9adbc4054b8e2b3ebdd5c63326f52ec4fc","tests/data/sha512_224/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha512_224/test2.output.bin":"cb5de67a5f215eb179fa45a2bb3f1b4583bbd2f510c90c21486aa47054f9745a","tests/data/sha512_224/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha512_224/test3.output.bin":"2a664dfa12b7b792709bea1a44b64eba03862a0ca60e251e99c6e05f94467c79","tests/data/sha512_256/test1.input.bin":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","tests/data/sha512_256/test1.output.bin":"5a480c713c47fb00a9b4943583ca0401fc147cce25efdc2594f958a4aeeafe48","tests/data/sha512_256/test2.input.bin":"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592","tests/data/sha512_256/test2.output.bin":"906e1d233a2d982ffe13f14b9bdc9c4229857dfdd5ec17be732d8fa4b7cc00cc","tests/data/sha512_256/test3.input.bin":"ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c","tests/data/sha512_256/test3.output.bin":"5ecc2545c93c4465c022b07ee5ff58d9b42fd91e1577bff7284e63f4c7c08d2e","tests/lib.rs":"52b23f0c2f72b88bfadca0dfdb0a0709e1157c53a9221d54484d75db4b747385"},"package":"9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"} \ No newline at end of file +{"files":{"Cargo.toml":"533f0168abf698c8281527c6802bcee7935fcacb299e998dcd9c1889968a388b","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"b4eb00df6e2a4d22518fcaa6a2b4646f249b3a3c9814509b22bd2091f1392ff1","benches/sha256.rs":"df310c190fa558ef95eacf3a60fc80c70c112caffe18eaa720414f778b573ec9","benches/sha512.rs":"34ca8f8073aa6ca288eb1f8cc1e58d6ecd7ef014097c2eec18c048f4fc7621c4","examples/sha256sum.rs":"82f5c111cfc3c6db386b2e1ed300e0f45cd781d6b0f291537e3db9f390dfb79b","examples/sha512sum.rs":"ba7690db22ff7ac7f5884bde6896a54ac6a82f05802e118d2f8c5458198687a6","src/consts.rs":"06e7bae76155291d1f896b72b625500859fbcfb80ee948ab3919620c96320610","src/lib.rs":"58cdecb2802e96c0bca56f21a06e7bf3f99f7b49d09fcfba88b5e00cf5edd769","src/sha256.rs":"8a97517a52fb057862d9f7a69b1dfa47f6aff19b31cc984b84eb29fcfda6e54d","src/sha256_utils.rs":"51093ea29330d179842f94dd97c5201386f576c90540edecdf8e2e0536f5b149","src/sha512.rs":"6be91c8a9ae54c4f1ee6c9c9e7e74d9473f44a958092df072c640b1165e2d1c6","src/sha512_utils.rs":"9008fe48d99c36e04276e68fc136975b6ef9e16ec35ef26d9e8027e47eb4545e","tests/data/sha224.blb":"b20c77259744a50b96e73c602e8473bf811f820f072cf3313d3f254d1d532f30","tests/data/sha256.blb":"9f984fbe1f9b89115db731d9058036dcdaf450d03d732a0a8cf6fb16c7e08a92","tests/data/sha256_one_million_a.bin":"80d1189477563e1b5206b2749f1afe4807e5705e8bd77887a60187a712156688","tests/data/sha384.blb":"305f96c4237a2aeb5d9b66cf30a13d5b41b749c6c8cb079192f45bd81ad404e3","tests/data/sha512.blb":"e3c964b9a735473cf14e64953a0dfee9d98e445ba242d439ffef216e9cfe36e6","tests/data/sha512_224.blb":"8baa081f40124f5a69892d8f1e06867acba094358ad6304b60405210af27160b","tests/data/sha512_256.blb":"f1f15c1040958ed32bc1c44d2947c7827f55e53107e026535343840176cb3608","tests/data/sha512_one_million_a.bin":"a872d736156b28b7784fcc124cfb9993ed31707f1754a0a448d26bf84f5cc7f5","tests/lib.rs":"02425927cf6b73988612fbfd34060f064034273c8c7853e3cc32e9a370b1d44e"},"package":"7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"} \ No newline at end of file diff --git a/third_party/rust/sha2/Cargo.toml b/third_party/rust/sha2/Cargo.toml index 8a062c76c088..5561060f6226 100644 --- a/third_party/rust/sha2/Cargo.toml +++ b/third_party/rust/sha2/Cargo.toml @@ -12,34 +12,39 @@ [package] name = "sha2" -version = "0.7.1" +version = "0.8.0" authors = ["RustCrypto Developers"] description = "SHA-2 hash functions" documentation = "https://docs.rs/sha2" keywords = ["crypto", "sha2", "hash", "digest"] categories = ["cryptography", "no-std"] -license = "MIT/Apache-2.0" +license = "MIT OR Apache-2.0" repository = "https://github.com/RustCrypto/hashes" [dependencies.block-buffer] -version = "0.3" - -[dependencies.byte-tools] -version = "0.2" +version = "0.7" [dependencies.digest] -version = "0.7" +version = "0.8" [dependencies.fake-simd] version = "0.1" +[dependencies.opaque-debug] +version = "0.2" + [dependencies.sha2-asm] version = "0.5" optional = true [dev-dependencies.digest] -version = "^0.7.1" +version = "0.8" features = ["dev"] +[dev-dependencies.hex-literal] +version = "0.1" + [features] asm = ["sha2-asm"] +default = ["std"] +std = ["digest/std"] [badges.travis-ci] repository = "RustCrypto/hashes" diff --git a/third_party/rust/sha2/benches/sha256.rs b/third_party/rust/sha2/benches/sha256.rs index fdb80f664ec7..aa604f6208fa 100644 --- a/third_party/rust/sha2/benches/sha256.rs +++ b/third_party/rust/sha2/benches/sha256.rs @@ -4,4 +4,4 @@ extern crate digest; extern crate sha2; -bench_digest!(sha2::Sha256); +bench!(sha2::Sha256); diff --git a/third_party/rust/sha2/benches/sha512.rs b/third_party/rust/sha2/benches/sha512.rs index 69dd87b44274..071dfc880840 100644 --- a/third_party/rust/sha2/benches/sha512.rs +++ b/third_party/rust/sha2/benches/sha512.rs @@ -4,4 +4,4 @@ extern crate digest; extern crate sha2; -bench_digest!(sha2::Sha512); +bench!(sha2::Sha512); diff --git a/third_party/rust/sha2/src/lib.rs b/third_party/rust/sha2/src/lib.rs index 4f01d20bb7bd..9b72eb24ecd4 100644 --- a/third_party/rust/sha2/src/lib.rs +++ b/third_party/rust/sha2/src/lib.rs @@ -1,4 +1,4 @@ -//! An implementation of the SHA-2 cryptographic hash algorithms. +//! An implementation of the [SHA-2][1] cryptographic hash algorithms. //! //! There are 6 standard algorithms specified in the SHA-2 standard: //! @@ -19,58 +19,52 @@ //! //! # Usage //! -//! An example of using `Sha256` is: -//! //! ```rust -//! use sha2::{Sha256, Digest}; +//! # #[macro_use] extern crate hex_literal; +//! # extern crate sha2; +//! # fn main() { +//! use sha2::{Sha256, Sha512, Digest}; //! //! // create a Sha256 object -//! let mut hasher = Sha256::default(); +//! let mut hasher = Sha256::new(); //! //! // write input message //! hasher.input(b"hello world"); //! //! // read hash digest and consume hasher -//! let output = hasher.result(); +//! let result = hasher.result(); //! -//! assert_eq!(output[..], [0xb9, 0x4d, 0x27, 0xb9, 0x93, 0x4d, 0x3e, 0x08, -//! 0xa5, 0x2e, 0x52, 0xd7, 0xda, 0x7d, 0xab, 0xfa, -//! 0xc4, 0x84, 0xef, 0xe3, 0x7a, 0x53, 0x80, 0xee, -//! 0x90, 0x88, 0xf7, 0xac, 0xe2, 0xef, 0xcd, 0xe9]); -//! ``` +//! assert_eq!(result[..], hex!(" +//! b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 +//! ")[..]); //! -//! An example of using `Sha512` is: -//! -//! ```rust -//! use sha2::{Sha512, Digest}; -//! -//! // create a Sha512 object -//! let mut hasher = Sha512::default(); -//! -//! // write input message +//! // same for Sha512 +//! let mut hasher = Sha512::new(); //! hasher.input(b"hello world"); +//! let result = hasher.result(); //! -//! // read hash digest and consume hasher -//! let output = hasher.result(); -//! -//! assert_eq!(output[..], [0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, -//! 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02, 0xf2, 0xb4, -//! 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, -//! 0x9b, 0xcd, 0x3c, 0xa8, 0x6d, 0x4c, 0xd8, 0x6f, -//! 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, -//! 0x70, 0xda, 0x34, 0x25, 0x5b, 0x45, 0xb0, 0xcf, -//! 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d, -//! 0xc5, 0x54, 0x2e, 0x93, 0xae, 0x9c, 0xd7, 0x6f][..]); +//! assert_eq!(result[..], hex!(" +//! 309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f +//! 989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f +//! ")[..]); +//! # } //! ``` - +//! +//! Also see [RustCrypto/hashes][2] readme. +//! +//! [1]: https://en.wikipedia.org/wiki/SHA-2 +//! [2]: https://github.com/RustCrypto/hashes #![no_std] -extern crate byte_tools; -#[macro_use] -extern crate digest; +#![doc(html_logo_url = + "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] extern crate block_buffer; extern crate fake_simd as simd; +#[macro_use] extern crate opaque_debug; +#[macro_use] pub extern crate digest; #[cfg(feature = "asm")] extern crate sha2_asm; +#[cfg(feature = "std")] +extern crate std; mod consts; #[cfg(not(feature = "asm"))] diff --git a/third_party/rust/sha2/src/sha256.rs b/third_party/rust/sha2/src/sha256.rs index 6de9c6c29af9..95763dbfc894 100644 --- a/third_party/rust/sha2/src/sha256.rs +++ b/third_party/rust/sha2/src/sha256.rs @@ -1,8 +1,8 @@ -use digest; +use digest::{Input, BlockInput, FixedOutput, Reset}; use digest::generic_array::GenericArray; use digest::generic_array::typenum::{U28, U32, U64}; -use block_buffer::BlockBuffer512; -use byte_tools::write_u32v_be; +use block_buffer::BlockBuffer; +use block_buffer::byteorder::{BE, ByteOrder}; use consts::{STATE_LEN, H224, H256}; @@ -12,7 +12,7 @@ use sha256_utils::compress256; use sha2_asm::compress256; type BlockSize = U64; -pub type Block = [u8; 64]; +type Block = GenericArray; /// A structure that represents that state of a digest computation for the /// SHA-2 512 family of digest functions @@ -24,8 +24,9 @@ struct Engine256State { impl Engine256State { fn new(h: &[u32; STATE_LEN]) -> Engine256State { Engine256State { h: *h } } - pub fn process_block(&mut self, data: &Block) { - compress256(&mut self.h, data); + pub fn process_block(&mut self, block: &Block) { + let block = unsafe { &*(block.as_ptr() as *const [u8; 64]) }; + compress256(&mut self.h, block); } } @@ -34,7 +35,7 @@ impl Engine256State { #[derive(Clone)] struct Engine256 { len: u64, - buffer: BlockBuffer512, + buffer: BlockBuffer, state: Engine256State, } @@ -57,9 +58,13 @@ impl Engine256 { fn finish(&mut self) { let self_state = &mut self.state; let l = self.len; - // TODO: replace with `len_padding_be` method - let l = if cfg!(target_endian = "little") { l.to_be() } else { l.to_le() }; - self.buffer.len_padding(l, |input| self_state.process_block(input)); + self.buffer.len64_padding::(l, |b| self_state.process_block(b)); + } + + fn reset(&mut self, h: &[u32; STATE_LEN]) { + self.len = 0; + self.buffer.reset(); + self.state = Engine256State::new(h); } } @@ -74,25 +79,33 @@ impl Default for Sha256 { fn default() -> Self { Sha256 { engine: Engine256::new(&H256) } } } -impl digest::BlockInput for Sha256 { +impl BlockInput for Sha256 { type BlockSize = BlockSize; } -impl digest::Input for Sha256 { - fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +impl Input for Sha256 { + fn input>(&mut self, input: B) { + self.engine.input(input.as_ref()); + } } -impl digest::FixedOutput for Sha256 { +impl FixedOutput for Sha256 { type OutputSize = U32; fn fixed_result(mut self) -> GenericArray { self.engine.finish(); let mut out = GenericArray::default(); - write_u32v_be(out.as_mut_slice(), &self.engine.state.h); + BE::write_u32_into(&self.engine.state.h, out.as_mut_slice()); out } } +impl Reset for Sha256 { + fn reset(&mut self) { + self.engine.reset(&H256); + } +} + /// The SHA-256 hash algorithm with the SHA-224 initial hash value. The result /// is truncated to 224 bits. #[derive(Clone)] @@ -104,24 +117,35 @@ impl Default for Sha224 { fn default() -> Self { Sha224 { engine: Engine256::new(&H224) } } } -impl digest::BlockInput for Sha224 { +impl BlockInput for Sha224 { type BlockSize = BlockSize; } -impl digest::Input for Sha224 { - fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +impl Input for Sha224 { + fn input>(&mut self, input: B) { + self.engine.input(input.as_ref()); + } } -impl digest::FixedOutput for Sha224 { +impl FixedOutput for Sha224 { type OutputSize = U28; fn fixed_result(mut self) -> GenericArray { self.engine.finish(); let mut out = GenericArray::default(); - write_u32v_be(out.as_mut_slice(), &self.engine.state.h[..7]); + BE::write_u32_into(&self.engine.state.h[..7], out.as_mut_slice()); out } } +impl Reset for Sha224 { + fn reset(&mut self) { + self.engine.reset(&H224); + } +} + impl_opaque_debug!(Sha224); impl_opaque_debug!(Sha256); + +impl_write!(Sha224); +impl_write!(Sha256); diff --git a/third_party/rust/sha2/src/sha256_utils.rs b/third_party/rust/sha2/src/sha256_utils.rs index 0a9d22b19362..6931665c34d0 100644 --- a/third_party/rust/sha2/src/sha256_utils.rs +++ b/third_party/rust/sha2/src/sha256_utils.rs @@ -2,8 +2,7 @@ use simd::u32x4; use consts::{BLOCK_LEN, K32X4}; -use byte_tools::{read_u32v_be}; -use sha256::Block; +use block_buffer::byteorder::{BE, ByteOrder}; /// Not an intrinsic, but works like an unaligned load. #[inline] @@ -260,8 +259,8 @@ fn sha256_digest_block_u32(state: &mut [u32; 8], block: &[u32; 16]) { /// implemented by any CPU (at the time of this writing), and so they are /// emulated in this library until the instructions become more common, and gain /// support in LLVM (and GCC, etc.). -pub fn compress256(state: &mut [u32; 8], block: &Block) { +pub fn compress256(state: &mut [u32; 8], block: &[u8; 64]) { let mut block_u32 = [0u32; BLOCK_LEN]; - read_u32v_be(&mut block_u32[..], block); + BE::read_u32_into(block, &mut block_u32[..]); sha256_digest_block_u32(state, &block_u32); } diff --git a/third_party/rust/sha2/src/sha512.rs b/third_party/rust/sha2/src/sha512.rs index b22cfeba92df..6b39ae1ed5f6 100644 --- a/third_party/rust/sha2/src/sha512.rs +++ b/third_party/rust/sha2/src/sha512.rs @@ -1,8 +1,8 @@ -use digest; +use digest::{Input, BlockInput, FixedOutput, Reset}; use digest::generic_array::GenericArray; use digest::generic_array::typenum::{U28, U32, U48, U64, U128}; -use block_buffer::BlockBuffer1024; -use byte_tools::{write_u64v_be, write_u32_be}; +use block_buffer::BlockBuffer; +use block_buffer::byteorder::{BE, ByteOrder}; use consts::{STATE_LEN, H384, H512, H512_TRUNC_224, H512_TRUNC_256}; @@ -12,7 +12,7 @@ use sha512_utils::compress512; use sha2_asm::compress512; type BlockSize = U128; -pub type Block = [u8; 128]; +type Block = GenericArray; /// A structure that represents that state of a digest computation for the /// SHA-2 512 family of digest functions @@ -24,8 +24,9 @@ struct Engine512State { impl Engine512State { fn new(h: &[u64; 8]) -> Engine512State { Engine512State { h: *h } } - pub fn process_block(&mut self, data: &Block) { - compress512(&mut self.h, data); + pub fn process_block(&mut self, block: &Block) { + let block = unsafe { &*(block.as_ptr() as *const [u8; 128])}; + compress512(&mut self.h, block); } } @@ -33,8 +34,8 @@ impl Engine512State { /// contains the logic necessary to perform the final calculations. #[derive(Clone)] struct Engine512 { - len: (u64, u64), // TODO: replace with u128 on stabilization - buffer: BlockBuffer1024, + len: (u64, u64), // TODO: replace with u128 on MSRV bump + buffer: BlockBuffer, state: Engine512State, } @@ -57,16 +58,14 @@ impl Engine512 { fn finish(&mut self) { let self_state = &mut self.state; - let (mut hi, mut lo) = self.len; - // TODO: change `len_padding_u128` to use BE - if cfg!(target_endian = "little") { - hi = hi.to_be(); - lo = lo.to_be(); - } else { - hi = hi.to_le(); - lo = lo.to_le(); - }; - self.buffer.len_padding_u128(hi, lo, |d| self_state.process_block(d)); + let (hi, lo) = self.len; + self.buffer.len128_padding_be(hi, lo, |d| self_state.process_block(d)); + } + + fn reset(&mut self, h: &[u64; STATE_LEN]) { + self.len = (0, 0); + self.buffer.reset(); + self.state = Engine512State::new(h); } } @@ -81,27 +80,33 @@ impl Default for Sha512 { fn default() -> Self { Sha512 { engine: Engine512::new(&H512) } } } -impl digest::BlockInput for Sha512 { +impl BlockInput for Sha512 { type BlockSize = BlockSize; } -impl digest::Input for Sha512 { - fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +impl Input for Sha512 { + fn input>(&mut self, input: B) { + self.engine.input(input.as_ref()); + } } -impl digest::FixedOutput for Sha512 { +impl FixedOutput for Sha512 { type OutputSize = U64; fn fixed_result(mut self) -> GenericArray { self.engine.finish(); let mut out = GenericArray::default(); - write_u64v_be(out.as_mut_slice(), &self.engine.state.h[..]); + BE::write_u64_into(&self.engine.state.h[..], out.as_mut_slice()); out } } - +impl Reset for Sha512 { + fn reset(&mut self) { + self.engine.reset(&H512); + } +} /// The SHA-512 hash algorithm with the SHA-384 initial hash value. The result /// is truncated to 384 bits. @@ -114,27 +119,33 @@ impl Default for Sha384 { fn default() -> Self { Sha384 { engine: Engine512::new(&H384) } } } -impl digest::BlockInput for Sha384 { +impl BlockInput for Sha384 { type BlockSize = BlockSize; } -impl digest::Input for Sha384 { - fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +impl Input for Sha384 { + fn input>(&mut self, input: B) { + self.engine.input(input.as_ref()); + } } -impl digest::FixedOutput for Sha384 { +impl FixedOutput for Sha384 { type OutputSize = U48; fn fixed_result(mut self) -> GenericArray { self.engine.finish(); let mut out = GenericArray::default(); - write_u64v_be(out.as_mut_slice(), &self.engine.state.h[..6]); + BE::write_u64_into(&self.engine.state.h[..6], out.as_mut_slice()); out } } - +impl Reset for Sha384 { + fn reset(&mut self) { + self.engine.reset(&H384); + } +} /// The SHA-512 hash algorithm with the SHA-512/256 initial hash value. The /// result is truncated to 256 bits. @@ -149,26 +160,34 @@ impl Default for Sha512Trunc256 { } } -impl digest::BlockInput for Sha512Trunc256 { +impl BlockInput for Sha512Trunc256 { type BlockSize = BlockSize; } -impl digest::Input for Sha512Trunc256 { - fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +impl Input for Sha512Trunc256 { + fn input>(&mut self, input: B) { + self.engine.input(input.as_ref()); + } } -impl digest::FixedOutput for Sha512Trunc256 { +impl FixedOutput for Sha512Trunc256 { type OutputSize = U32; fn fixed_result(mut self) -> GenericArray { self.engine.finish(); let mut out = GenericArray::default(); - write_u64v_be(out.as_mut_slice(), &self.engine.state.h[..4]); + BE::write_u64_into(&self.engine.state.h[..4], out.as_mut_slice()); out } } +impl Reset for Sha512Trunc256 { + fn reset(&mut self) { + self.engine.reset(&H512_TRUNC_256); + } +} + /// The SHA-512 hash algorithm with the SHA-512/224 initial hash value. /// The result is truncated to 224 bits. #[derive(Clone)] @@ -182,28 +201,41 @@ impl Default for Sha512Trunc224 { } } -impl digest::BlockInput for Sha512Trunc224 { +impl BlockInput for Sha512Trunc224 { type BlockSize = BlockSize; } -impl digest::Input for Sha512Trunc224 { - fn process(&mut self, msg: &[u8]) { self.engine.input(msg); } +impl Input for Sha512Trunc224 { + fn input>(&mut self, input: B) { + self.engine.input(input.as_ref()); + } } -impl digest::FixedOutput for Sha512Trunc224 { +impl FixedOutput for Sha512Trunc224 { type OutputSize = U28; fn fixed_result(mut self) -> GenericArray { self.engine.finish(); let mut out = GenericArray::default(); - write_u64v_be(&mut out[..24], &self.engine.state.h[..3]); - write_u32_be(&mut out[24..28], (self.engine.state.h[3] >> 32) as u32); + BE::write_u64_into(&self.engine.state.h[..3], &mut out[..24]); + BE::write_u32(&mut out[24..28], (self.engine.state.h[3] >> 32) as u32); out } } +impl Reset for Sha512Trunc224 { + fn reset(&mut self) { + self.engine.reset(&H512_TRUNC_224); + } +} + impl_opaque_debug!(Sha384); impl_opaque_debug!(Sha512); impl_opaque_debug!(Sha512Trunc224); impl_opaque_debug!(Sha512Trunc256); + +impl_write!(Sha384); +impl_write!(Sha512); +impl_write!(Sha512Trunc224); +impl_write!(Sha512Trunc256); diff --git a/third_party/rust/sha2/src/sha512_utils.rs b/third_party/rust/sha2/src/sha512_utils.rs index 0ab6ad3077c0..ba80e198985d 100644 --- a/third_party/rust/sha2/src/sha512_utils.rs +++ b/third_party/rust/sha2/src/sha512_utils.rs @@ -2,8 +2,7 @@ use simd::u64x2; use consts::{BLOCK_LEN, K64X2}; -use byte_tools::{read_u64v_be}; -use sha512::Block; +use block_buffer::byteorder::{BE, ByteOrder}; /// Not an intrinsic, but works like an unaligned load. #[inline] @@ -280,8 +279,8 @@ pub fn sha512_digest_block_u64(state: &mut [u64; 8], block: &[u64; 16]) { /// } /// ``` /// -pub fn compress512(state: &mut [u64; 8], block: &Block) { +pub fn compress512(state: &mut [u64; 8], block: &[u8; 128]) { let mut block_u64 = [0u64; BLOCK_LEN]; - read_u64v_be(&mut block_u64[..], block); + BE::read_u64_into(block, &mut block_u64[..]); sha512_digest_block_u64(state, &block_u64); } diff --git a/third_party/rust/sha2/tests/data/sha224.blb b/third_party/rust/sha2/tests/data/sha224.blb new file mode 100644 index 000000000000..50759c294c8a Binary files /dev/null and b/third_party/rust/sha2/tests/data/sha224.blb differ diff --git a/third_party/rust/sha2/tests/data/sha256.blb b/third_party/rust/sha2/tests/data/sha256.blb new file mode 100644 index 000000000000..2096fd4ec0cd Binary files /dev/null and b/third_party/rust/sha2/tests/data/sha256.blb differ diff --git a/third_party/rust/sha2/tests/data/sha256_one_million_a.bin b/third_party/rust/sha2/tests/data/sha256_one_million_a.bin new file mode 100644 index 000000000000..59757633dd56 --- /dev/null +++ b/third_party/rust/sha2/tests/data/sha256_one_million_a.bin @@ -0,0 +1 @@ +n\>gH m9, \ No newline at end of file diff --git a/third_party/rust/sha2/tests/data/sha384.blb b/third_party/rust/sha2/tests/data/sha384.blb new file mode 100644 index 000000000000..7e9062497c83 Binary files /dev/null and b/third_party/rust/sha2/tests/data/sha384.blb differ diff --git a/third_party/rust/sha2/tests/data/sha512.blb b/third_party/rust/sha2/tests/data/sha512.blb new file mode 100644 index 000000000000..b073a77cb7fc Binary files /dev/null and b/third_party/rust/sha2/tests/data/sha512.blb differ diff --git a/third_party/rust/sha2/tests/data/sha512_224.blb b/third_party/rust/sha2/tests/data/sha512_224.blb new file mode 100644 index 000000000000..4d2ef87ff011 Binary files /dev/null and b/third_party/rust/sha2/tests/data/sha512_224.blb differ diff --git a/third_party/rust/sha2/tests/data/sha512_256.blb b/third_party/rust/sha2/tests/data/sha512_256.blb new file mode 100644 index 000000000000..5346c9494df4 Binary files /dev/null and b/third_party/rust/sha2/tests/data/sha512_256.blb differ diff --git a/third_party/rust/sha2/tests/data/sha512_one_million_a.bin b/third_party/rust/sha2/tests/data/sha512_one_million_a.bin new file mode 100644 index 000000000000..6edb1d6cf2a7 Binary files /dev/null and b/third_party/rust/sha2/tests/data/sha512_one_million_a.bin differ diff --git a/third_party/rust/sha2/tests/lib.rs b/third_party/rust/sha2/tests/lib.rs index e386fcc46105..1d3c2f16233f 100644 --- a/third_party/rust/sha2/tests/lib.rs +++ b/third_party/rust/sha2/tests/lib.rs @@ -3,52 +3,23 @@ extern crate digest; extern crate sha2; -use digest::dev::{Test, main_test, one_million_a}; +use digest::dev::{one_million_a, digest_test}; + +new_test!(sha224_main, "sha224", sha2::Sha224, digest_test); +new_test!(sha256_main, "sha256", sha2::Sha256, digest_test); +new_test!(sha384_main, "sha384", sha2::Sha384, digest_test); +new_test!(sha512_main, "sha512", sha2::Sha512, digest_test); +new_test!(sha512_224_main, "sha512_224", sha2::Sha512Trunc224, digest_test); +new_test!(sha512_256_main, "sha512_256", sha2::Sha512Trunc256, digest_test); #[test] -fn sha2_224_main() { - let tests = new_tests!("sha224/test1", "sha224/test2", "sha224/test3"); - main_test::(&tests); -} - -#[test] -fn sha2_256_main() { - let tests = new_tests!("sha256/test1", "sha256/test2", "sha256/test3"); - main_test::(&tests); -} - -#[test] -fn sha2_384_main() { - let tests = new_tests!("sha384/test1", "sha384/test2", "sha384/test3"); - main_test::(&tests); -} - -#[test] -fn sha2_512_main() { - let tests = new_tests!("sha512/test1", "sha512/test2", "sha512/test3"); - main_test::(&tests); -} - -#[test] -fn sha2_512_trunc_256_main() { - let tests = new_tests!("sha512_256/test1", "sha512_256/test2", "sha512_256/test3"); - main_test::(&tests); -} - -#[test] -fn sha2_512_trunc_224_main() { - let tests = new_tests!("sha512_224/test1", "sha512_224/test2", "sha512_224/test3"); - main_test::(&tests); -} - -#[test] -fn sha2_256_1million_a() { - let output = include_bytes!("data/sha256/one_million_a.output.bin"); +fn sha256_1million_a() { + let output = include_bytes!("data/sha256_one_million_a.bin"); one_million_a::(output); } #[test] -fn sha2_512_1million_a() { - let output = include_bytes!("data/sha512/one_million_a.output.bin"); +fn sha512_1million_a() { + let output = include_bytes!("data/sha512_one_million_a.bin"); one_million_a::(output); -} \ No newline at end of file +}